Commit 9449c18a authored by Robert Griesemer's avatar Robert Griesemer

cmd/api: rewrite using go/types

- adjusted test files so that they actually type-check
- adjusted go1.txt, go1.1.txt, next.txt
- to run, provide build tag: api_tool

Fixes #4538.

R=bradfitz
CC=golang-dev
https://golang.org/cl/12300043
parent de04bf24
......@@ -92,6 +92,7 @@ pkg encoding/json, method (Number) String() string
pkg encoding/json, type Number string
pkg encoding/xml, func EscapeText(io.Writer, []uint8) error
pkg encoding/xml, method (*Encoder) Indent(string, string)
pkg encoding/xml, method (Encoder) ReadFrom(io.Reader) (int64, error)
pkg encoding/xml, type Decoder struct, DefaultSpace string
pkg go/ast, func NewCommentMap(*token.FileSet, Node, []*CommentGroup) CommentMap
pkg go/ast, method (CommentMap) Comments() []*CommentGroup
......@@ -1700,6 +1701,7 @@ pkg testing, method (BenchmarkResult) AllocsPerOp() int64
pkg testing, method (BenchmarkResult) MemString() string
pkg testing, type BenchmarkResult struct, MemAllocs uint64
pkg testing, type BenchmarkResult struct, MemBytes uint64
pkg text/template, method (Template) ErrorContext(parse.Node) (string, string)
pkg text/template/parse, const NodeChain NodeType
pkg text/template/parse, const NodeNil NodeType
pkg text/template/parse, method (*ChainNode) Add(string)
......
......@@ -391,6 +391,18 @@ pkg crypto/dsa, var ErrInvalidPublicKey error
pkg crypto/ecdsa, func GenerateKey(elliptic.Curve, io.Reader) (*PrivateKey, error)
pkg crypto/ecdsa, func Sign(io.Reader, *PrivateKey, []uint8) (*big.Int, *big.Int, error)
pkg crypto/ecdsa, func Verify(*PublicKey, []uint8, *big.Int, *big.Int) bool
pkg crypto/ecdsa, method (PrivateKey) Add(*big.Int, *big.Int, *big.Int, *big.Int) (*big.Int, *big.Int)
pkg crypto/ecdsa, method (PrivateKey) Double(*big.Int, *big.Int) (*big.Int, *big.Int)
pkg crypto/ecdsa, method (PrivateKey) IsOnCurve(*big.Int, *big.Int) bool
pkg crypto/ecdsa, method (PrivateKey) Params() *elliptic.CurveParams
pkg crypto/ecdsa, method (PrivateKey) ScalarBaseMult([]uint8) (*big.Int, *big.Int)
pkg crypto/ecdsa, method (PrivateKey) ScalarMult(*big.Int, *big.Int, []uint8) (*big.Int, *big.Int)
pkg crypto/ecdsa, method (PublicKey) Add(*big.Int, *big.Int, *big.Int, *big.Int) (*big.Int, *big.Int)
pkg crypto/ecdsa, method (PublicKey) Double(*big.Int, *big.Int) (*big.Int, *big.Int)
pkg crypto/ecdsa, method (PublicKey) IsOnCurve(*big.Int, *big.Int) bool
pkg crypto/ecdsa, method (PublicKey) Params() *elliptic.CurveParams
pkg crypto/ecdsa, method (PublicKey) ScalarBaseMult([]uint8) (*big.Int, *big.Int)
pkg crypto/ecdsa, method (PublicKey) ScalarMult(*big.Int, *big.Int, []uint8) (*big.Int, *big.Int)
pkg crypto/ecdsa, type PrivateKey struct
pkg crypto/ecdsa, type PrivateKey struct, D *big.Int
pkg crypto/ecdsa, type PrivateKey struct, embedded PublicKey
......@@ -1614,6 +1626,7 @@ pkg debug/elf, method (NType) GoString() string
pkg debug/elf, method (NType) String() string
pkg debug/elf, method (OSABI) GoString() string
pkg debug/elf, method (OSABI) String() string
pkg debug/elf, method (Prog) ReadAt([]uint8, int64) (int, error)
pkg debug/elf, method (ProgFlag) GoString() string
pkg debug/elf, method (ProgFlag) String() string
pkg debug/elf, method (ProgType) GoString() string
......@@ -1630,6 +1643,7 @@ pkg debug/elf, method (R_SPARC) GoString() string
pkg debug/elf, method (R_SPARC) String() string
pkg debug/elf, method (R_X86_64) GoString() string
pkg debug/elf, method (R_X86_64) String() string
pkg debug/elf, method (Section) ReadAt([]uint8, int64) (int, error)
pkg debug/elf, method (SectionFlag) GoString() string
pkg debug/elf, method (SectionFlag) String() string
pkg debug/elf, method (SectionIndex) GoString() string
......@@ -1674,7 +1688,7 @@ pkg debug/elf, type Header32 struct
pkg debug/elf, type Header32 struct, Ehsize uint16
pkg debug/elf, type Header32 struct, Entry uint32
pkg debug/elf, type Header32 struct, Flags uint32
pkg debug/elf, type Header32 struct, Ident [EI_NIDENT]uint8
pkg debug/elf, type Header32 struct, Ident [16]uint8
pkg debug/elf, type Header32 struct, Machine uint16
pkg debug/elf, type Header32 struct, Phentsize uint16
pkg debug/elf, type Header32 struct, Phnum uint16
......@@ -1689,7 +1703,7 @@ pkg debug/elf, type Header64 struct
pkg debug/elf, type Header64 struct, Ehsize uint16
pkg debug/elf, type Header64 struct, Entry uint64
pkg debug/elf, type Header64 struct, Flags uint32
pkg debug/elf, type Header64 struct, Ident [EI_NIDENT]uint8
pkg debug/elf, type Header64 struct, Ident [16]uint8
pkg debug/elf, type Header64 struct, Machine uint16
pkg debug/elf, type Header64 struct, Phentsize uint16
pkg debug/elf, type Header64 struct, Phnum uint16
......@@ -1911,7 +1925,9 @@ pkg debug/macho, method (Dysymtab) Raw() []uint8
pkg debug/macho, method (LoadBytes) Raw() []uint8
pkg debug/macho, method (LoadCmd) GoString() string
pkg debug/macho, method (LoadCmd) String() string
pkg debug/macho, method (Section) ReadAt([]uint8, int64) (int, error)
pkg debug/macho, method (Segment) Raw() []uint8
pkg debug/macho, method (Segment) ReadAt([]uint8, int64) (int, error)
pkg debug/macho, method (Symtab) Raw() []uint8
pkg debug/macho, type Cpu uint32
pkg debug/macho, type Dylib struct
......@@ -2154,6 +2170,7 @@ pkg debug/pe, method (*File) Section(string) *Section
pkg debug/pe, method (*FormatError) Error() string
pkg debug/pe, method (*Section) Data() ([]uint8, error)
pkg debug/pe, method (*Section) Open() io.ReadSeeker
pkg debug/pe, method (Section) ReadAt([]uint8, int64) (int, error)
pkg debug/pe, type File struct
pkg debug/pe, type File struct, Sections []*Section
pkg debug/pe, type File struct, embedded FileHeader
......@@ -2408,6 +2425,13 @@ pkg encoding/xml, method (*UnsupportedTypeError) Error() string
pkg encoding/xml, method (CharData) Copy() CharData
pkg encoding/xml, method (Comment) Copy() Comment
pkg encoding/xml, method (Directive) Copy() Directive
pkg encoding/xml, method (Encoder) Available() int
pkg encoding/xml, method (Encoder) Buffered() int
pkg encoding/xml, method (Encoder) Flush() error
pkg encoding/xml, method (Encoder) Write([]uint8) (int, error)
pkg encoding/xml, method (Encoder) WriteByte(uint8) error
pkg encoding/xml, method (Encoder) WriteRune(int32) (int, error)
pkg encoding/xml, method (Encoder) WriteString(string) (int, error)
pkg encoding/xml, method (ProcInst) Copy() ProcInst
pkg encoding/xml, method (StartElement) Copy() StartElement
pkg encoding/xml, method (UnmarshalError) Error() string
......@@ -3659,7 +3683,7 @@ pkg image/draw, func Draw(Image, image.Rectangle, image.Image, image.Point, Op)
pkg image/draw, func DrawMask(Image, image.Rectangle, image.Image, image.Point, image.Image, image.Point, Op)
pkg image/draw, type Image interface { At, Bounds, ColorModel, Set }
pkg image/draw, type Image interface, At(int, int) color.Color
pkg image/draw, type Image interface, Bounds() Rectangle
pkg image/draw, type Image interface, Bounds() image.Rectangle
pkg image/draw, type Image interface, ColorModel() color.Model
pkg image/draw, type Image interface, Set(int, int, color.Color)
pkg image/draw, type Op int
......@@ -4164,7 +4188,7 @@ pkg math, func Trunc(float64) float64
pkg math, func Y0(float64) float64
pkg math, func Y1(float64) float64
pkg math, func Yn(int, float64) float64
pkg math/big, const MaxBase ideal-int
pkg math/big, const MaxBase ideal-char
pkg math/big, func NewInt(int64) *Int
pkg math/big, func NewRat(int64, int64) *Rat
pkg math/big, method (*Int) Abs(*Int) *Int
......@@ -5266,6 +5290,14 @@ pkg os/exec, method (*Cmd) StdoutPipe() (io.ReadCloser, error)
pkg os/exec, method (*Cmd) Wait() error
pkg os/exec, method (*Error) Error() string
pkg os/exec, method (*ExitError) Error() string
pkg os/exec, method (ExitError) Exited() bool
pkg os/exec, method (ExitError) Pid() int
pkg os/exec, method (ExitError) String() string
pkg os/exec, method (ExitError) Success() bool
pkg os/exec, method (ExitError) Sys() interface{}
pkg os/exec, method (ExitError) SysUsage() interface{}
pkg os/exec, method (ExitError) SystemTime() time.Duration
pkg os/exec, method (ExitError) UserTime() time.Duration
pkg os/exec, type Cmd struct
pkg os/exec, type Cmd struct, Args []string
pkg os/exec, type Cmd struct, Dir string
......@@ -5687,6 +5719,7 @@ pkg runtime, type MemProfileRecord struct, Stack0 [32]uintptr
pkg runtime, type MemStats struct
pkg runtime, type MemStats struct, Alloc uint64
pkg runtime, type MemStats struct, BuckHashSys uint64
pkg runtime, type MemStats struct, BySize [61]struct
pkg runtime, type MemStats struct, DebugGC bool
pkg runtime, type MemStats struct, EnableGC bool
pkg runtime, type MemStats struct, Frees uint64
......@@ -28803,12 +28836,12 @@ pkg syscall (windows-386), type InterfaceInfo struct, BroadcastAddress SockaddrG
pkg syscall (windows-386), type InterfaceInfo struct, Flags uint32
pkg syscall (windows-386), type InterfaceInfo struct, Netmask SockaddrGen
pkg syscall (windows-386), type IpAdapterInfo struct
pkg syscall (windows-386), type IpAdapterInfo struct, AdapterName [MAX_ADAPTER_NAME_LENGTH + 4]uint8
pkg syscall (windows-386), type IpAdapterInfo struct, Address [MAX_ADAPTER_ADDRESS_LENGTH]uint8
pkg syscall (windows-386), type IpAdapterInfo struct, AdapterName [260]uint8
pkg syscall (windows-386), type IpAdapterInfo struct, Address [8]uint8
pkg syscall (windows-386), type IpAdapterInfo struct, AddressLength uint32
pkg syscall (windows-386), type IpAdapterInfo struct, ComboIndex uint32
pkg syscall (windows-386), type IpAdapterInfo struct, CurrentIpAddress *IpAddrString
pkg syscall (windows-386), type IpAdapterInfo struct, Description [MAX_ADAPTER_DESCRIPTION_LENGTH + 4]uint8
pkg syscall (windows-386), type IpAdapterInfo struct, Description [132]uint8
pkg syscall (windows-386), type IpAdapterInfo struct, DhcpEnabled uint32
pkg syscall (windows-386), type IpAdapterInfo struct, DhcpServer IpAddrString
pkg syscall (windows-386), type IpAdapterInfo struct, GatewayList IpAddrString
......@@ -28828,14 +28861,14 @@ pkg syscall (windows-386), type IpAddrString struct, IpMask IpMaskString
pkg syscall (windows-386), type IpAddrString struct, Next *IpAddrString
pkg syscall (windows-386), type IpAddressString struct
pkg syscall (windows-386), type IpAddressString struct, String [16]uint8
pkg syscall (windows-386), type IpMaskString IpAddressString
pkg syscall (windows-386), type IpMaskString struct
pkg syscall (windows-386), type LazyDLL struct
pkg syscall (windows-386), type LazyDLL struct, Name string
pkg syscall (windows-386), type LazyProc struct
pkg syscall (windows-386), type LazyProc struct, Name string
pkg syscall (windows-386), type MibIfRow struct
pkg syscall (windows-386), type MibIfRow struct, AdminStatus uint32
pkg syscall (windows-386), type MibIfRow struct, Descr [MAXLEN_IFDESCR]uint8
pkg syscall (windows-386), type MibIfRow struct, Descr [256]uint8
pkg syscall (windows-386), type MibIfRow struct, DescrLen uint32
pkg syscall (windows-386), type MibIfRow struct, InDiscards uint32
pkg syscall (windows-386), type MibIfRow struct, InErrors uint32
......@@ -28846,7 +28879,7 @@ pkg syscall (windows-386), type MibIfRow struct, InUnknownProtos uint32
pkg syscall (windows-386), type MibIfRow struct, Index uint32
pkg syscall (windows-386), type MibIfRow struct, LastChange uint32
pkg syscall (windows-386), type MibIfRow struct, Mtu uint32
pkg syscall (windows-386), type MibIfRow struct, Name [MAX_INTERFACE_NAME_LEN]uint16
pkg syscall (windows-386), type MibIfRow struct, Name [256]uint16
pkg syscall (windows-386), type MibIfRow struct, OperStatus uint32
pkg syscall (windows-386), type MibIfRow struct, OutDiscards uint32
pkg syscall (windows-386), type MibIfRow struct, OutErrors uint32
......@@ -28854,7 +28887,7 @@ pkg syscall (windows-386), type MibIfRow struct, OutNUcastPkts uint32
pkg syscall (windows-386), type MibIfRow struct, OutOctets uint32
pkg syscall (windows-386), type MibIfRow struct, OutQLen uint32
pkg syscall (windows-386), type MibIfRow struct, OutUcastPkts uint32
pkg syscall (windows-386), type MibIfRow struct, PhysAddr [MAXLEN_PHYSADDR]uint8
pkg syscall (windows-386), type MibIfRow struct, PhysAddr [8]uint8
pkg syscall (windows-386), type MibIfRow struct, PhysAddrLen uint32
pkg syscall (windows-386), type MibIfRow struct, Speed uint32
pkg syscall (windows-386), type MibIfRow struct, Type uint32
......@@ -28943,7 +28976,7 @@ pkg syscall (windows-386), type Timezoneinformation struct, DaylightName [32]uin
pkg syscall (windows-386), type Timezoneinformation struct, StandardBias int32
pkg syscall (windows-386), type Timezoneinformation struct, StandardDate Systemtime
pkg syscall (windows-386), type Timezoneinformation struct, StandardName [32]uint16
pkg syscall (windows-386), type Token Handle
pkg syscall (windows-386), type Token uintptr
pkg syscall (windows-386), type Tokenprimarygroup struct
pkg syscall (windows-386), type Tokenprimarygroup struct, PrimaryGroup *SID
pkg syscall (windows-386), type Tokenuser struct
......@@ -28962,11 +28995,11 @@ pkg syscall (windows-386), type WSABuf struct
pkg syscall (windows-386), type WSABuf struct, Buf *uint8
pkg syscall (windows-386), type WSABuf struct, Len uint32
pkg syscall (windows-386), type WSAData struct
pkg syscall (windows-386), type WSAData struct, Description [WSADESCRIPTION_LEN + 1]uint8
pkg syscall (windows-386), type WSAData struct, Description [257]uint8
pkg syscall (windows-386), type WSAData struct, HighVersion uint16
pkg syscall (windows-386), type WSAData struct, MaxSockets uint16
pkg syscall (windows-386), type WSAData struct, MaxUdpDg uint16
pkg syscall (windows-386), type WSAData struct, SystemStatus [WSASYS_STATUS_LEN + 1]uint8
pkg syscall (windows-386), type WSAData struct, SystemStatus [129]uint8
pkg syscall (windows-386), type WSAData struct, VendorInfo *uint8
pkg syscall (windows-386), type WSAData struct, Version uint16
pkg syscall (windows-386), type WaitStatus struct
......@@ -28982,7 +29015,7 @@ pkg syscall (windows-386), type Win32finddata struct
pkg syscall (windows-386), type Win32finddata struct, AlternateFileName [13]uint16
pkg syscall (windows-386), type Win32finddata struct, CreationTime Filetime
pkg syscall (windows-386), type Win32finddata struct, FileAttributes uint32
pkg syscall (windows-386), type Win32finddata struct, FileName [MAX_PATH - 1]uint16
pkg syscall (windows-386), type Win32finddata struct, FileName [259]uint16
pkg syscall (windows-386), type Win32finddata struct, FileSizeHigh uint32
pkg syscall (windows-386), type Win32finddata struct, FileSizeLow uint32
pkg syscall (windows-386), type Win32finddata struct, LastAccessTime Filetime
......@@ -29732,12 +29765,12 @@ pkg syscall (windows-amd64), type InterfaceInfo struct, BroadcastAddress Sockadd
pkg syscall (windows-amd64), type InterfaceInfo struct, Flags uint32
pkg syscall (windows-amd64), type InterfaceInfo struct, Netmask SockaddrGen
pkg syscall (windows-amd64), type IpAdapterInfo struct
pkg syscall (windows-amd64), type IpAdapterInfo struct, AdapterName [MAX_ADAPTER_NAME_LENGTH + 4]uint8
pkg syscall (windows-amd64), type IpAdapterInfo struct, Address [MAX_ADAPTER_ADDRESS_LENGTH]uint8
pkg syscall (windows-amd64), type IpAdapterInfo struct, AdapterName [260]uint8
pkg syscall (windows-amd64), type IpAdapterInfo struct, Address [8]uint8
pkg syscall (windows-amd64), type IpAdapterInfo struct, AddressLength uint32
pkg syscall (windows-amd64), type IpAdapterInfo struct, ComboIndex uint32
pkg syscall (windows-amd64), type IpAdapterInfo struct, CurrentIpAddress *IpAddrString
pkg syscall (windows-amd64), type IpAdapterInfo struct, Description [MAX_ADAPTER_DESCRIPTION_LENGTH + 4]uint8
pkg syscall (windows-amd64), type IpAdapterInfo struct, Description [132]uint8
pkg syscall (windows-amd64), type IpAdapterInfo struct, DhcpEnabled uint32
pkg syscall (windows-amd64), type IpAdapterInfo struct, DhcpServer IpAddrString
pkg syscall (windows-amd64), type IpAdapterInfo struct, GatewayList IpAddrString
......@@ -29757,14 +29790,14 @@ pkg syscall (windows-amd64), type IpAddrString struct, IpMask IpMaskString
pkg syscall (windows-amd64), type IpAddrString struct, Next *IpAddrString
pkg syscall (windows-amd64), type IpAddressString struct
pkg syscall (windows-amd64), type IpAddressString struct, String [16]uint8
pkg syscall (windows-amd64), type IpMaskString IpAddressString
pkg syscall (windows-amd64), type IpMaskString struct
pkg syscall (windows-amd64), type LazyDLL struct
pkg syscall (windows-amd64), type LazyDLL struct, Name string
pkg syscall (windows-amd64), type LazyProc struct
pkg syscall (windows-amd64), type LazyProc struct, Name string
pkg syscall (windows-amd64), type MibIfRow struct
pkg syscall (windows-amd64), type MibIfRow struct, AdminStatus uint32
pkg syscall (windows-amd64), type MibIfRow struct, Descr [MAXLEN_IFDESCR]uint8
pkg syscall (windows-amd64), type MibIfRow struct, Descr [256]uint8
pkg syscall (windows-amd64), type MibIfRow struct, DescrLen uint32
pkg syscall (windows-amd64), type MibIfRow struct, InDiscards uint32
pkg syscall (windows-amd64), type MibIfRow struct, InErrors uint32
......@@ -29775,7 +29808,7 @@ pkg syscall (windows-amd64), type MibIfRow struct, InUnknownProtos uint32
pkg syscall (windows-amd64), type MibIfRow struct, Index uint32
pkg syscall (windows-amd64), type MibIfRow struct, LastChange uint32
pkg syscall (windows-amd64), type MibIfRow struct, Mtu uint32
pkg syscall (windows-amd64), type MibIfRow struct, Name [MAX_INTERFACE_NAME_LEN]uint16
pkg syscall (windows-amd64), type MibIfRow struct, Name [256]uint16
pkg syscall (windows-amd64), type MibIfRow struct, OperStatus uint32
pkg syscall (windows-amd64), type MibIfRow struct, OutDiscards uint32
pkg syscall (windows-amd64), type MibIfRow struct, OutErrors uint32
......@@ -29783,7 +29816,7 @@ pkg syscall (windows-amd64), type MibIfRow struct, OutNUcastPkts uint32
pkg syscall (windows-amd64), type MibIfRow struct, OutOctets uint32
pkg syscall (windows-amd64), type MibIfRow struct, OutQLen uint32
pkg syscall (windows-amd64), type MibIfRow struct, OutUcastPkts uint32
pkg syscall (windows-amd64), type MibIfRow struct, PhysAddr [MAXLEN_PHYSADDR]uint8
pkg syscall (windows-amd64), type MibIfRow struct, PhysAddr [8]uint8
pkg syscall (windows-amd64), type MibIfRow struct, PhysAddrLen uint32
pkg syscall (windows-amd64), type MibIfRow struct, Speed uint32
pkg syscall (windows-amd64), type MibIfRow struct, Type uint32
......@@ -29872,7 +29905,7 @@ pkg syscall (windows-amd64), type Timezoneinformation struct, DaylightName [32]u
pkg syscall (windows-amd64), type Timezoneinformation struct, StandardBias int32
pkg syscall (windows-amd64), type Timezoneinformation struct, StandardDate Systemtime
pkg syscall (windows-amd64), type Timezoneinformation struct, StandardName [32]uint16
pkg syscall (windows-amd64), type Token Handle
pkg syscall (windows-amd64), type Token uintptr
pkg syscall (windows-amd64), type Tokenprimarygroup struct
pkg syscall (windows-amd64), type Tokenprimarygroup struct, PrimaryGroup *SID
pkg syscall (windows-amd64), type Tokenuser struct
......@@ -29891,11 +29924,11 @@ pkg syscall (windows-amd64), type WSABuf struct
pkg syscall (windows-amd64), type WSABuf struct, Buf *uint8
pkg syscall (windows-amd64), type WSABuf struct, Len uint32
pkg syscall (windows-amd64), type WSAData struct
pkg syscall (windows-amd64), type WSAData struct, Description [WSADESCRIPTION_LEN + 1]uint8
pkg syscall (windows-amd64), type WSAData struct, Description [257]uint8
pkg syscall (windows-amd64), type WSAData struct, HighVersion uint16
pkg syscall (windows-amd64), type WSAData struct, MaxSockets uint16
pkg syscall (windows-amd64), type WSAData struct, MaxUdpDg uint16
pkg syscall (windows-amd64), type WSAData struct, SystemStatus [WSASYS_STATUS_LEN + 1]uint8
pkg syscall (windows-amd64), type WSAData struct, SystemStatus [129]uint8
pkg syscall (windows-amd64), type WSAData struct, VendorInfo *uint8
pkg syscall (windows-amd64), type WSAData struct, Version uint16
pkg syscall (windows-amd64), type WaitStatus struct
......@@ -29911,7 +29944,7 @@ pkg syscall (windows-amd64), type Win32finddata struct
pkg syscall (windows-amd64), type Win32finddata struct, AlternateFileName [13]uint16
pkg syscall (windows-amd64), type Win32finddata struct, CreationTime Filetime
pkg syscall (windows-amd64), type Win32finddata struct, FileAttributes uint32
pkg syscall (windows-amd64), type Win32finddata struct, FileName [MAX_PATH - 1]uint16
pkg syscall (windows-amd64), type Win32finddata struct, FileName [259]uint16
pkg syscall (windows-amd64), type Win32finddata struct, FileSizeHigh uint32
pkg syscall (windows-amd64), type Win32finddata struct, FileSizeLow uint32
pkg syscall (windows-amd64), type Win32finddata struct, LastAccessTime Filetime
......@@ -30029,7 +30062,7 @@ pkg syscall, const IP_MULTICAST_LOOP ideal-int
pkg syscall, const IP_MULTICAST_TTL ideal-int
pkg syscall, const IP_TOS ideal-int
pkg syscall, const IP_TTL ideal-int
pkg syscall, const ImplementsGetwd bool
pkg syscall, const ImplementsGetwd ideal-bool
pkg syscall, const O_APPEND ideal-int
pkg syscall, const O_ASYNC ideal-int
pkg syscall, const O_CLOEXEC ideal-int
......@@ -30596,7 +30629,7 @@ pkg unicode, const MaxRune ideal-char
pkg unicode, const ReplacementChar ideal-char
pkg unicode, const TitleCase ideal-int
pkg unicode, const UpperCase ideal-int
pkg unicode, const UpperLower ideal-int
pkg unicode, const UpperLower ideal-char
pkg unicode, const Version ideal-string
pkg unicode, func Is(*RangeTable, int32) bool
pkg unicode, func IsControl(int32) bool
......@@ -30843,8 +30876,3 @@ pkg unicode/utf8, func RuneLen(int32) int
pkg unicode/utf8, func RuneStart(uint8) bool
pkg unicode/utf8, func Valid([]uint8) bool
pkg unicode/utf8, func ValidString(string) bool
pkg unsafe, func Alignof(ArbitraryType) uintptr
pkg unsafe, func Offsetof(ArbitraryType) uintptr
pkg unsafe, func Sizeof(ArbitraryType) uintptr
pkg unsafe, type ArbitraryType int
pkg unsafe, type Pointer *ArbitraryType
pkg archive/zip, func RegisterCompressor(uint16, Compressor)
pkg archive/zip, func RegisterDecompressor(uint16, Decompressor)
pkg archive/zip, type Compressor func(io.Writer) (io.WriteCloser, error)
pkg archive/zip, type Decompressor func(io.Reader) io.ReadCloser
pkg container/heap, func Fix(Interface, int)
pkg container/list, method (*List) MoveAfter(*Element, *Element)
pkg container/list, method (*List) MoveBefore(*Element, *Element)
......@@ -8,18 +12,18 @@ pkg crypto/cipher, type AEAD interface, NonceSize() int
pkg crypto/cipher, type AEAD interface, Open([]uint8, []uint8, []uint8, []uint8) ([]uint8, error)
pkg crypto/cipher, type AEAD interface, Overhead() int
pkg crypto/cipher, type AEAD interface, Seal([]uint8, []uint8, []uint8, []uint8) []uint8
pkg crypto/md5, func Sum([]uint8) [Size]uint8
pkg crypto/md5, func Sum([]uint8) [16]uint8
pkg crypto/rsa, const PSSSaltLengthAuto ideal-int
pkg crypto/rsa, const PSSSaltLengthEqualsHash ideal-int
pkg crypto/rsa, func SignPSS(io.Reader, *PrivateKey, crypto.Hash, []uint8, *PSSOptions) ([]uint8, error)
pkg crypto/rsa, func VerifyPSS(*PublicKey, crypto.Hash, []uint8, []uint8, *PSSOptions) error
pkg crypto/rsa, type PSSOptions struct
pkg crypto/rsa, type PSSOptions struct, SaltLength int
pkg crypto/sha1, func Sum([]uint8) [Size]uint8
pkg crypto/sha256, func Sum224([]uint8) [Size224]uint8
pkg crypto/sha256, func Sum256([]uint8) [Size]uint8
pkg crypto/sha512, func Sum384([]uint8) [Size384]uint8
pkg crypto/sha512, func Sum512([]uint8) [Size]uint8
pkg crypto/sha1, func Sum([]uint8) [20]uint8
pkg crypto/sha256, func Sum224([]uint8) [28]uint8
pkg crypto/sha256, func Sum256([]uint8) [32]uint8
pkg crypto/sha512, func Sum384([]uint8) [48]uint8
pkg crypto/sha512, func Sum512([]uint8) [64]uint8
pkg crypto/subtle, func ConstantTimeLessOrEq(int, int) int
pkg crypto/tls, const TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16
pkg crypto/tls, const TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16
......@@ -38,6 +42,7 @@ pkg flag, type Getter interface { Get, Set, String }
pkg flag, type Getter interface, Get() interface{}
pkg flag, type Getter interface, Set(string) error
pkg flag, type Getter interface, String() string
pkg flag, var CommandLine *FlagSet
pkg go/ast, type SliceExpr struct, Max Expr
pkg go/ast, type TypeAssertExpr struct, Lparen token.Pos
pkg go/ast, type TypeAssertExpr struct, Rparen token.Pos
......@@ -31701,20 +31706,136 @@ pkg syscall (openbsd-amd64-cgo), type WaitStatus uint32
pkg syscall (openbsd-amd64-cgo), var Stderr int
pkg syscall (openbsd-amd64-cgo), var Stdin int
pkg syscall (openbsd-amd64-cgo), var Stdout int
pkg syscall (windows-386), const BASE_PROTOCOL ideal-int
pkg syscall (windows-386), const ERROR_HANDLE_EOF Errno
pkg syscall (windows-386), const FILE_SKIP_COMPLETION_PORT_ON_SUCCESS ideal-int
pkg syscall (windows-386), const FILE_SKIP_SET_EVENT_ON_HANDLE ideal-int
pkg syscall (windows-386), const LAYERED_PROTOCOL ideal-int
pkg syscall (windows-386), const MAX_PROTOCOL_CHAIN ideal-int
pkg syscall (windows-386), const NetSetupDomainName ideal-int
pkg syscall (windows-386), const NetSetupUnjoined ideal-int
pkg syscall (windows-386), const NetSetupUnknownStatus ideal-int
pkg syscall (windows-386), const NetSetupWorkgroupName ideal-int
pkg syscall (windows-386), const PFL_HIDDEN ideal-int
pkg syscall (windows-386), const PFL_MATCHES_PROTOCOL_ZERO ideal-int
pkg syscall (windows-386), const PFL_MULTIPLE_PROTO_ENTRIES ideal-int
pkg syscall (windows-386), const PFL_NETWORKDIRECT_PROVIDER ideal-int
pkg syscall (windows-386), const PFL_RECOMMENDED_PROTO_ENTRY ideal-int
pkg syscall (windows-386), const PROCESS_TERMINATE ideal-int
pkg syscall (windows-386), const WSAPROTOCOL_LEN ideal-int
pkg syscall (windows-386), const XP1_CONNECTIONLESS ideal-int
pkg syscall (windows-386), const XP1_CONNECT_DATA ideal-int
pkg syscall (windows-386), const XP1_DISCONNECT_DATA ideal-int
pkg syscall (windows-386), const XP1_EXPEDITED_DATA ideal-int
pkg syscall (windows-386), const XP1_GRACEFUL_CLOSE ideal-int
pkg syscall (windows-386), const XP1_GUARANTEED_DELIVERY ideal-int
pkg syscall (windows-386), const XP1_GUARANTEED_ORDER ideal-int
pkg syscall (windows-386), const XP1_IFS_HANDLES ideal-int
pkg syscall (windows-386), const XP1_MESSAGE_ORIENTED ideal-int
pkg syscall (windows-386), const XP1_MULTIPOINT_CONTROL_PLANE ideal-int
pkg syscall (windows-386), const XP1_MULTIPOINT_DATA_PLANE ideal-int
pkg syscall (windows-386), const XP1_PARTIAL_MESSAGE ideal-int
pkg syscall (windows-386), const XP1_PSEUDO_STREAM ideal-int
pkg syscall (windows-386), const XP1_QOS_SUPPORTED ideal-int
pkg syscall (windows-386), const XP1_SAN_SUPPORT_SDP ideal-int
pkg syscall (windows-386), const XP1_SUPPORT_BROADCAST ideal-int
pkg syscall (windows-386), const XP1_SUPPORT_MULTIPOINT ideal-int
pkg syscall (windows-386), const XP1_UNI_RECV ideal-int
pkg syscall (windows-386), const XP1_UNI_SEND ideal-int
pkg syscall (windows-386), func LoadSetFileCompletionNotificationModes() error
pkg syscall (windows-386), func NetGetJoinInformation(*uint16, **uint16, *uint32) error
pkg syscall (windows-386), func SetFileCompletionNotificationModes(Handle, uint8) error
pkg syscall (windows-386), func WSAEnumProtocols(*int32, *WSAProtocolInfo, *uint32) (int32, error)
pkg syscall (windows-386), type IpMaskString struct, String [16]uint8
pkg syscall (windows-386), type WSAProtocolChain struct
pkg syscall (windows-386), type WSAProtocolChain struct, ChainEntries [7]uint32
pkg syscall (windows-386), type WSAProtocolChain struct, ChainLen int32
pkg syscall (windows-386), type WSAProtocolInfo struct
pkg syscall (windows-386), type WSAProtocolInfo struct, AddressFamily int32
pkg syscall (windows-386), type WSAProtocolInfo struct, CatalogEntryId uint32
pkg syscall (windows-386), type WSAProtocolInfo struct, MaxSockAddr int32
pkg syscall (windows-386), type WSAProtocolInfo struct, MessageSize uint32
pkg syscall (windows-386), type WSAProtocolInfo struct, MinSockAddr int32
pkg syscall (windows-386), type WSAProtocolInfo struct, NetworkByteOrder int32
pkg syscall (windows-386), type WSAProtocolInfo struct, Protocol int32
pkg syscall (windows-386), type WSAProtocolInfo struct, ProtocolChain WSAProtocolChain
pkg syscall (windows-386), type WSAProtocolInfo struct, ProtocolMaxOffset int32
pkg syscall (windows-386), type WSAProtocolInfo struct, ProtocolName [256]uint16
pkg syscall (windows-386), type WSAProtocolInfo struct, ProviderFlags uint32
pkg syscall (windows-386), type WSAProtocolInfo struct, ProviderId GUID
pkg syscall (windows-386), type WSAProtocolInfo struct, ProviderReserved uint32
pkg syscall (windows-386), type WSAProtocolInfo struct, SecurityScheme int32
pkg syscall (windows-386), type WSAProtocolInfo struct, ServiceFlags1 uint32
pkg syscall (windows-386), type WSAProtocolInfo struct, ServiceFlags2 uint32
pkg syscall (windows-386), type WSAProtocolInfo struct, ServiceFlags3 uint32
pkg syscall (windows-386), type WSAProtocolInfo struct, ServiceFlags4 uint32
pkg syscall (windows-386), type WSAProtocolInfo struct, SocketType int32
pkg syscall (windows-386), type WSAProtocolInfo struct, Version int32
pkg syscall (windows-amd64), const BASE_PROTOCOL ideal-int
pkg syscall (windows-amd64), const ERROR_HANDLE_EOF Errno
pkg syscall (windows-amd64), const FILE_SKIP_COMPLETION_PORT_ON_SUCCESS ideal-int
pkg syscall (windows-amd64), const FILE_SKIP_SET_EVENT_ON_HANDLE ideal-int
pkg syscall (windows-amd64), const LAYERED_PROTOCOL ideal-int
pkg syscall (windows-amd64), const MAX_PROTOCOL_CHAIN ideal-int
pkg syscall (windows-amd64), const NetSetupDomainName ideal-int
pkg syscall (windows-amd64), const NetSetupUnjoined ideal-int
pkg syscall (windows-amd64), const NetSetupUnknownStatus ideal-int
pkg syscall (windows-amd64), const NetSetupWorkgroupName ideal-int
pkg syscall (windows-amd64), const PFL_HIDDEN ideal-int
pkg syscall (windows-amd64), const PFL_MATCHES_PROTOCOL_ZERO ideal-int
pkg syscall (windows-amd64), const PFL_MULTIPLE_PROTO_ENTRIES ideal-int
pkg syscall (windows-amd64), const PFL_NETWORKDIRECT_PROVIDER ideal-int
pkg syscall (windows-amd64), const PFL_RECOMMENDED_PROTO_ENTRY ideal-int
pkg syscall (windows-amd64), const PROCESS_TERMINATE ideal-int
pkg syscall (windows-amd64), const WSAPROTOCOL_LEN ideal-int
pkg syscall (windows-amd64), const XP1_CONNECTIONLESS ideal-int
pkg syscall (windows-amd64), const XP1_CONNECT_DATA ideal-int
pkg syscall (windows-amd64), const XP1_DISCONNECT_DATA ideal-int
pkg syscall (windows-amd64), const XP1_EXPEDITED_DATA ideal-int
pkg syscall (windows-amd64), const XP1_GRACEFUL_CLOSE ideal-int
pkg syscall (windows-amd64), const XP1_GUARANTEED_DELIVERY ideal-int
pkg syscall (windows-amd64), const XP1_GUARANTEED_ORDER ideal-int
pkg syscall (windows-amd64), const XP1_IFS_HANDLES ideal-int
pkg syscall (windows-amd64), const XP1_MESSAGE_ORIENTED ideal-int
pkg syscall (windows-amd64), const XP1_MULTIPOINT_CONTROL_PLANE ideal-int
pkg syscall (windows-amd64), const XP1_MULTIPOINT_DATA_PLANE ideal-int
pkg syscall (windows-amd64), const XP1_PARTIAL_MESSAGE ideal-int
pkg syscall (windows-amd64), const XP1_PSEUDO_STREAM ideal-int
pkg syscall (windows-amd64), const XP1_QOS_SUPPORTED ideal-int
pkg syscall (windows-amd64), const XP1_SAN_SUPPORT_SDP ideal-int
pkg syscall (windows-amd64), const XP1_SUPPORT_BROADCAST ideal-int
pkg syscall (windows-amd64), const XP1_SUPPORT_MULTIPOINT ideal-int
pkg syscall (windows-amd64), const XP1_UNI_RECV ideal-int
pkg syscall (windows-amd64), const XP1_UNI_SEND ideal-int
pkg syscall (windows-amd64), func LoadSetFileCompletionNotificationModes() error
pkg syscall (windows-amd64), func NetGetJoinInformation(*uint16, **uint16, *uint32) error
pkg syscall (windows-amd64), func SetFileCompletionNotificationModes(Handle, uint8) error
pkg syscall (windows-amd64), func WSAEnumProtocols(*int32, *WSAProtocolInfo, *uint32) (int32, error)
pkg syscall (windows-amd64), type IpMaskString struct, String [16]uint8
pkg syscall (windows-amd64), type WSAProtocolChain struct
pkg syscall (windows-amd64), type WSAProtocolChain struct, ChainEntries [7]uint32
pkg syscall (windows-amd64), type WSAProtocolChain struct, ChainLen int32
pkg syscall (windows-amd64), type WSAProtocolInfo struct
pkg syscall (windows-amd64), type WSAProtocolInfo struct, AddressFamily int32
pkg syscall (windows-amd64), type WSAProtocolInfo struct, CatalogEntryId uint32
pkg syscall (windows-amd64), type WSAProtocolInfo struct, MaxSockAddr int32
pkg syscall (windows-amd64), type WSAProtocolInfo struct, MessageSize uint32
pkg syscall (windows-amd64), type WSAProtocolInfo struct, MinSockAddr int32
pkg syscall (windows-amd64), type WSAProtocolInfo struct, NetworkByteOrder int32
pkg syscall (windows-amd64), type WSAProtocolInfo struct, Protocol int32
pkg syscall (windows-amd64), type WSAProtocolInfo struct, ProtocolChain WSAProtocolChain
pkg syscall (windows-amd64), type WSAProtocolInfo struct, ProtocolMaxOffset int32
pkg syscall (windows-amd64), type WSAProtocolInfo struct, ProtocolName [256]uint16
pkg syscall (windows-amd64), type WSAProtocolInfo struct, ProviderFlags uint32
pkg syscall (windows-amd64), type WSAProtocolInfo struct, ProviderId GUID
pkg syscall (windows-amd64), type WSAProtocolInfo struct, ProviderReserved uint32
pkg syscall (windows-amd64), type WSAProtocolInfo struct, SecurityScheme int32
pkg syscall (windows-amd64), type WSAProtocolInfo struct, ServiceFlags1 uint32
pkg syscall (windows-amd64), type WSAProtocolInfo struct, ServiceFlags2 uint32
pkg syscall (windows-amd64), type WSAProtocolInfo struct, ServiceFlags3 uint32
pkg syscall (windows-amd64), type WSAProtocolInfo struct, ServiceFlags4 uint32
pkg syscall (windows-amd64), type WSAProtocolInfo struct, SocketType int32
pkg syscall (windows-amd64), type WSAProtocolInfo struct, Version int32
pkg testing, func RegisterCover(Cover)
pkg testing, type Cover struct
pkg testing, type Cover struct, Blocks map[string][]CoverBlock
// Copyright 2012 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.
package main
import (
"fmt"
"go/ast"
"log"
"reflect"
)
const debugClone = false
// TODO(bradfitz): delete this function (and whole file) once
// http://golang.org/issue/4380 is fixed.
func clone(i interface{}) (cloned interface{}) {
if debugClone {
defer func() {
if !reflect.DeepEqual(i, cloned) {
log.Printf("cloned %T doesn't match: in=%#v out=%#v", i, i, cloned)
}
}()
}
switch v := i.(type) {
case nil:
return nil
case *ast.File:
o := &ast.File{
Doc: v.Doc, // shallow
Package: v.Package,
Comments: v.Comments, // shallow
Name: v.Name,
Scope: v.Scope,
}
for _, x := range v.Decls {
o.Decls = append(o.Decls, clone(x).(ast.Decl))
}
for _, x := range v.Imports {
o.Imports = append(o.Imports, clone(x).(*ast.ImportSpec))
}
for _, x := range v.Unresolved {
o.Unresolved = append(o.Unresolved, x)
}
return o
case *ast.GenDecl:
o := new(ast.GenDecl)
*o = *v
o.Specs = nil
for _, x := range v.Specs {
o.Specs = append(o.Specs, clone(x).(ast.Spec))
}
return o
case *ast.TypeSpec:
o := new(ast.TypeSpec)
*o = *v
o.Type = cloneExpr(v.Type)
return o
case *ast.InterfaceType:
o := new(ast.InterfaceType)
*o = *v
o.Methods = clone(v.Methods).(*ast.FieldList)
return o
case *ast.FieldList:
if v == nil {
return v
}
o := new(ast.FieldList)
*o = *v
o.List = nil
for _, x := range v.List {
o.List = append(o.List, clone(x).(*ast.Field))
}
return o
case *ast.Field:
o := &ast.Field{
Doc: v.Doc, // shallow
Type: cloneExpr(v.Type),
Tag: clone(v.Tag).(*ast.BasicLit),
Comment: v.Comment, // shallow
}
for _, x := range v.Names {
o.Names = append(o.Names, clone(x).(*ast.Ident))
}
return o
case *ast.FuncType:
if v == nil {
return v
}
return &ast.FuncType{
Func: v.Func,
Params: clone(v.Params).(*ast.FieldList),
Results: clone(v.Results).(*ast.FieldList),
}
case *ast.FuncDecl:
if v == nil {
return v
}
return &ast.FuncDecl{
Recv: clone(v.Recv).(*ast.FieldList),
Name: v.Name,
Type: clone(v.Type).(*ast.FuncType),
Body: v.Body, // shallow
}
case *ast.ValueSpec:
if v == nil {
return v
}
o := &ast.ValueSpec{
Type: cloneExpr(v.Type),
}
for _, x := range v.Names {
o.Names = append(o.Names, x)
}
for _, x := range v.Values {
o.Values = append(o.Values, cloneExpr(x))
}
return o
case *ast.CallExpr:
if v == nil {
return v
}
o := &ast.CallExpr{}
*o = *v
o.Args = cloneExprs(v.Args)
o.Fun = cloneExpr(v.Fun)
return o
case *ast.SelectorExpr:
if v == nil {
return nil
}
return &ast.SelectorExpr{
X: cloneExpr(v.X),
Sel: v.Sel,
}
case *ast.ArrayType:
return &ast.ArrayType{
Lbrack: v.Lbrack,
Len: cloneExpr(v.Len),
Elt: cloneExpr(v.Elt),
}
case *ast.StructType:
return &ast.StructType{
Struct: v.Struct,
Fields: clone(v.Fields).(*ast.FieldList),
Incomplete: v.Incomplete,
}
case *ast.StarExpr:
return &ast.StarExpr{
Star: v.Star,
X: cloneExpr(v.X),
}
case *ast.CompositeLit:
return &ast.CompositeLit{
Type: cloneExpr(v.Type),
Lbrace: v.Lbrace,
Elts: cloneExprs(v.Elts),
Rbrace: v.Rbrace,
}
case *ast.UnaryExpr:
return &ast.UnaryExpr{
OpPos: v.OpPos,
Op: v.Op,
X: cloneExpr(v.X),
}
case *ast.BinaryExpr:
return &ast.BinaryExpr{
OpPos: v.OpPos,
Op: v.Op,
X: cloneExpr(v.X),
Y: cloneExpr(v.Y),
}
case *ast.Ellipsis:
return &ast.Ellipsis{
Ellipsis: v.Ellipsis,
Elt: cloneExpr(v.Elt),
}
case *ast.KeyValueExpr:
return &ast.KeyValueExpr{
Key: cloneExpr(v.Key),
Colon: v.Colon,
Value: cloneExpr(v.Value),
}
case *ast.FuncLit:
return &ast.FuncLit{
Type: clone(v.Type).(*ast.FuncType),
Body: v.Body, // shallow
}
case *ast.MapType:
return &ast.MapType{
Map: v.Map,
Key: cloneExpr(v.Key),
Value: cloneExpr(v.Value),
}
case *ast.ParenExpr:
return &ast.ParenExpr{
Lparen: v.Lparen,
X: cloneExpr(v.X),
Rparen: v.Rparen,
}
case *ast.Ident, *ast.BasicLit:
return v
case *ast.ImportSpec:
return &ast.ImportSpec{
Doc: v.Doc, // shallow
Name: v.Name,
Path: clone(v.Path).(*ast.BasicLit),
Comment: v.Comment, // shallow
EndPos: v.EndPos,
}
case *ast.ChanType:
return &ast.ChanType{
Begin: v.Begin,
Arrow: v.Arrow,
Dir: v.Dir,
Value: cloneExpr(v.Value),
}
case *ast.TypeAssertExpr:
return &ast.TypeAssertExpr{
X: cloneExpr(v.X),
Type: cloneExpr(v.Type),
}
case *ast.IndexExpr:
return &ast.IndexExpr{
X: cloneExpr(v.X),
Index: cloneExpr(v.Index),
Lbrack: v.Lbrack,
Rbrack: v.Rbrack,
}
}
panic(fmt.Sprintf("Uncloneable type %T", i))
}
func cloneExpr(x ast.Expr) ast.Expr {
if x == nil {
return nil
}
return clone(x).(ast.Expr)
}
func cloneExprs(x []ast.Expr) []ast.Expr {
if x == nil {
return nil
}
o := make([]ast.Expr, len(x))
for i, x := range x {
o[i] = cloneExpr(x)
}
return o
}
// +build api_tool
// Copyright 2011 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.
// Api computes the exported API of a set of Go packages.
//
// BUG(bradfitz): Note that this tool is only currently suitable
// for use on the Go standard library, not arbitrary packages.
// Once the Go AST has type information, this tool will be more
// reliable without hard-coded hacks throughout.
// Binary api computes the exported API of a set of Go packages.
package main
import (
"bufio"
"bytes"
"errors"
"flag"
"fmt"
"go/ast"
"go/build"
"go/doc"
"go/parser"
"go/printer"
"go/token"
"io"
"io/ioutil"
"log"
"os"
"os/exec"
"path"
"path/filepath"
"regexp"
"runtime"
"sort"
"strconv"
"strings"
"code.google.com/p/go.tools/go/types"
)
// Flags
......@@ -130,35 +124,31 @@ func main() {
c.Compiler = build.Default.Compiler
}
var pkgs []string
var pkgNames []string
if flag.NArg() > 0 {
pkgs = flag.Args()
pkgNames = flag.Args()
} else {
stds, err := exec.Command("go", "list", "std").Output()
if err != nil {
log.Fatal(err)
}
pkgs = strings.Fields(string(stds))
pkgNames = strings.Fields(string(stds))
}
var featureCtx = make(map[string]map[string]bool) // feature -> context name -> true
for _, context := range contexts {
w := NewWalker()
w.context = context
for _, pkg := range pkgs {
w.wantedPkg[pkg] = true
}
w := NewWalker(context, filepath.Join(build.Default.GOROOT, "src/pkg"))
for _, pkg := range pkgs {
if strings.HasPrefix(pkg, "cmd/") {
continue
for _, name := range pkgNames {
// - Package "unsafe" contains special signatures requiring
// extra care when printing them - ignore since it is not
// going to change w/o a language change.
// - We don't care about the API of commands.
if name != "unsafe" && !strings.HasPrefix(name, "cmd/") {
w.export(w.Import(name))
}
if fi, err := os.Stat(filepath.Join(w.root, pkg)); err != nil || !fi.IsDir() {
log.Fatalf("no source in tree for package %q", pkg)
}
w.WalkPackage(pkg)
}
ctxName := contextName(context)
for _, f := range w.Features() {
if featureCtx[f] == nil {
......@@ -194,7 +184,7 @@ func main() {
if *checkFile == "" {
sort.Strings(features)
for _, f := range features {
fmt.Fprintf(bw, "%s\n", f)
fmt.Fprintln(bw, f)
}
return
}
......@@ -208,6 +198,22 @@ func main() {
fail = !compareAPI(bw, features, required, optional, exception)
}
// export emits the exported package features.
func (w *Walker) export(pkg *types.Package) {
if *verbose {
log.Println(pkg)
}
pop := w.pushScope("pkg " + pkg.Path())
w.current = pkg
scope := pkg.Scope()
for _, name := range scope.Names() {
if ast.IsExported(name) {
w.emitObj(scope.Lookup(name))
}
}
pop()
}
func set(items []string) map[string]bool {
s := make(map[string]bool)
for _, v := range items {
......@@ -304,53 +310,26 @@ func fileFeatures(filename string) []string {
return strings.Split(text, "\n")
}
// pkgSymbol represents a symbol in a package
type pkgSymbol struct {
pkg string // "net/http"
symbol string // "RoundTripper"
}
var fset = token.NewFileSet()
type Walker struct {
context *build.Context
root string
scope []string
features map[string]bool // set
lastConstType string
curPackageName string
curPackage *ast.Package
prevConstType map[pkgSymbol]string
constDep map[string]string // key's const identifier has type of future value const identifier
packageState map[string]loadState
interfaces map[pkgSymbol]*ast.InterfaceType
functionTypes map[pkgSymbol]string // symbol => return type
selectorFullPkg map[string]string // "http" => "net/http", updated by imports
wantedPkg map[string]bool // packages requested on the command line
context *build.Context
root string
scope []string
current *types.Package
features map[string]bool // set
imported map[string]*types.Package // packages already imported
}
func NewWalker() *Walker {
func NewWalker(context *build.Context, root string) *Walker {
return &Walker{
features: make(map[string]bool),
packageState: make(map[string]loadState),
interfaces: make(map[pkgSymbol]*ast.InterfaceType),
functionTypes: make(map[pkgSymbol]string),
selectorFullPkg: make(map[string]string),
wantedPkg: make(map[string]bool),
prevConstType: make(map[pkgSymbol]string),
root: filepath.Join(build.Default.GOROOT, "src/pkg"),
context: context,
root: root,
features: map[string]bool{},
imported: map[string]*types.Package{"unsafe": types.Unsafe},
}
}
// loadState is the state of a package's parsing.
type loadState int
const (
notLoaded loadState = iota
loading
loaded
)
func (w *Walker) Features() (fs []string) {
for f := range w.features {
fs = append(fs, f)
......@@ -359,127 +338,133 @@ func (w *Walker) Features() (fs []string) {
return
}
// fileDeps returns the imports in a file.
func fileDeps(f *ast.File) (pkgs []string) {
for _, is := range f.Imports {
fpkg, err := strconv.Unquote(is.Path.Value)
var parsedFileCache = make(map[string]*ast.File)
func (w *Walker) parseFile(dir, file string) (*ast.File, error) {
filename := filepath.Join(dir, file)
f, _ := parsedFileCache[filename]
if f != nil {
return f, nil
}
var err error
// generate missing context-dependent files.
if w.context != nil && file == fmt.Sprintf("zgoos_%s.go", w.context.GOOS) {
src := fmt.Sprintf("package runtime; const theGoos = `%s`", w.context.GOOS)
f, err = parser.ParseFile(fset, filename, src, 0)
if err != nil {
log.Fatalf("error unquoting import string %q: %v", is.Path.Value, err)
}
if fpkg != "C" {
pkgs = append(pkgs, fpkg)
log.Fatalf("incorrect generated file: %s", err)
}
}
return
}
var parsedFileCache = make(map[string]*ast.File)
if w.context != nil && file == fmt.Sprintf("zgoarch_%s.go", w.context.GOARCH) {
src := fmt.Sprintf("package runtime; const theGoarch = `%s`", w.context.GOARCH)
f, err = parser.ParseFile(fset, filename, src, 0)
if err != nil {
log.Fatalf("incorrect generated file: %s", err)
}
}
func parseFile(filename string) (*ast.File, error) {
f, ok := parsedFileCache[filename]
if !ok {
var err error
if f == nil {
f, err = parser.ParseFile(fset, filename, nil, 0)
if err != nil {
return nil, err
}
parsedFileCache[filename] = f
}
return clone(f).(*ast.File), nil
parsedFileCache[filename] = f
return f, nil
}
// WalkPackage walks all files in package `name'.
// WalkPackage does nothing if the package has already been loaded.
func (w *Walker) WalkPackage(name string) {
switch w.packageState[name] {
case loading:
log.Fatalf("import cycle loading package %q?", name)
case loaded:
return
func contains(list []string, s string) bool {
for _, t := range list {
if t == s {
return true
}
}
w.packageState[name] = loading
defer func() {
w.packageState[name] = loaded
}()
return false
}
// Importing is a sentinel taking the place in Walker.imported
// for a package that is in the process of being imported.
var importing types.Package
func (w *Walker) Import(name string) (pkg *types.Package) {
pkg = w.imported[name]
if pkg != nil {
if pkg == &importing {
log.Fatalf("cycle importing package %q", name)
}
return pkg
}
w.imported[name] = &importing
// Determine package files.
dir := filepath.Join(w.root, filepath.FromSlash(name))
if fi, err := os.Stat(dir); err != nil || !fi.IsDir() {
log.Fatalf("no source in tree for package %q", pkg)
}
ctxt := w.context
if ctxt == nil {
ctxt = &build.Default
context := w.context
if context == nil {
context = &build.Default
}
info, err := ctxt.ImportDir(dir, 0)
info, err := context.ImportDir(dir, 0)
if err != nil {
if strings.Contains(err.Error(), "no Go source files") {
if _, nogo := err.(*build.NoGoError); nogo {
return
}
log.Fatalf("pkg %q, dir %q: ScanDir: %v", name, dir, err)
}
filenames := append(append([]string{}, info.GoFiles...), info.CgoFiles...)
apkg := &ast.Package{
Files: make(map[string]*ast.File),
}
files := append(append([]string{}, info.GoFiles...), info.CgoFiles...)
for _, file := range files {
f, err := parseFile(filepath.Join(dir, file))
if err != nil {
log.Fatalf("error parsing package %s, file %s: %v", name, file, err)
// Certain files only exist when building for the specified context.
// Add them manually.
if name == "runtime" {
n := fmt.Sprintf("zgoos_%s.go", w.context.GOOS)
if !contains(filenames, n) {
filenames = append(filenames, n)
}
apkg.Files[file] = f
for _, dep := range fileDeps(f) {
w.WalkPackage(dep)
n = fmt.Sprintf("zgoarch_%s.go", w.context.GOARCH)
if !contains(filenames, n) {
filenames = append(filenames, n)
}
}
if *verbose {
log.Printf("package %s", name)
}
pop := w.pushScope("pkg " + name)
defer pop()
w.curPackageName = name
w.curPackage = apkg
w.constDep = map[string]string{}
for _, afile := range apkg.Files {
w.recordTypes(afile)
}
// Register all function declarations first.
for _, afile := range apkg.Files {
for _, di := range afile.Decls {
if d, ok := di.(*ast.FuncDecl); ok {
w.peekFuncDecl(d)
}
// Parse package files.
var files []*ast.File
for _, file := range filenames {
f, err := w.parseFile(dir, file)
if err != nil {
log.Fatalf("error parsing package %s: %s", name, err)
}
files = append(files, f)
}
for _, afile := range apkg.Files {
w.walkFile(afile)
// Type-check package files.
conf := types.Config{
IgnoreFuncBodies: true,
FakeImportC: true,
Import: func(imports map[string]*types.Package, name string) (*types.Package, error) {
pkg := w.Import(name)
imports[name] = pkg
return pkg, nil
},
}
w.resolveConstantDeps()
// Now that we're done walking types, vars and consts
// in the *ast.Package, use go/doc to do the rest
// (functions and methods). This is done here because
// go/doc is destructive. We can't use the
// *ast.Package after this.
dpkg := doc.New(apkg, name, doc.AllMethods)
for _, t := range dpkg.Types {
// Move funcs up to the top-level, not hiding in the Types.
dpkg.Funcs = append(dpkg.Funcs, t.Funcs...)
for _, m := range t.Methods {
w.walkFuncDecl(m.Decl)
pkg, err = conf.Check(name, fset, files, nil)
if err != nil {
ctxt := "<no context>"
if w.context != nil {
ctxt = fmt.Sprintf("%s-%s", w.context.GOOS, w.context.GOARCH)
}
log.Fatalf("error typechecking package %s: %s (%s)", name, err, ctxt)
}
for _, f := range dpkg.Funcs {
w.walkFuncDecl(f.Decl)
}
w.imported[name] = pkg
return
}
// pushScope enters a new scope (walking a package, type, node, etc)
......@@ -498,707 +483,310 @@ func (w *Walker) pushScope(name string) (popFunc func()) {
}
}
func (w *Walker) recordTypes(file *ast.File) {
for _, di := range file.Decls {
switch d := di.(type) {
case *ast.GenDecl:
switch d.Tok {
case token.TYPE:
for _, sp := range d.Specs {
ts := sp.(*ast.TypeSpec)
name := ts.Name.Name
if ast.IsExported(name) {
if it, ok := ts.Type.(*ast.InterfaceType); ok {
w.noteInterface(name, it)
}
}
}
}
func sortedMethodNames(typ *types.Interface) []string {
n := typ.NumMethods()
list := make([]string, n)
for i := range list {
list[i] = typ.Method(i).Name()
}
sort.Strings(list)
return list
}
func (w *Walker) writeType(buf *bytes.Buffer, typ types.Type) {
switch typ := typ.(type) {
case *types.Basic:
s := typ.Name()
switch typ.Kind() {
case types.UnsafePointer:
s = "unsafe.Pointer"
case types.UntypedBool:
s = "ideal-bool"
case types.UntypedInt:
s = "ideal-int"
case types.UntypedRune:
// "ideal-char" for compatibility with old tool
// TODO(gri) change to "ideal-rune"
s = "ideal-char"
case types.UntypedFloat:
s = "ideal-float"
case types.UntypedComplex:
s = "ideal-complex"
case types.UntypedString:
s = "ideal-string"
case types.UntypedNil:
panic("should never see untyped nil type")
default:
switch s {
case "byte":
s = "uint8"
case "rune":
s = "int32"
}
}
buf.WriteString(s)
case *types.Array:
fmt.Fprintf(buf, "[%d]", typ.Len())
w.writeType(buf, typ.Elem())
case *types.Slice:
buf.WriteString("[]")
w.writeType(buf, typ.Elem())
case *types.Struct:
buf.WriteString("struct")
case *types.Pointer:
buf.WriteByte('*')
w.writeType(buf, typ.Elem())
case *types.Tuple:
panic("should never see a tuple type")
case *types.Signature:
buf.WriteString("func")
w.writeSignature(buf, typ)
case *types.Interface:
buf.WriteString("interface{")
if typ.NumMethods() > 0 {
buf.WriteByte(' ')
buf.WriteString(strings.Join(sortedMethodNames(typ), ", "))
buf.WriteByte(' ')
}
buf.WriteString("}")
case *types.Map:
buf.WriteString("map[")
w.writeType(buf, typ.Key())
buf.WriteByte(']')
w.writeType(buf, typ.Elem())
case *types.Chan:
var s string
switch typ.Dir() {
case ast.SEND:
s = "chan<- "
case ast.RECV:
s = "<-chan "
default:
s = "chan "
}
}
}
buf.WriteString(s)
w.writeType(buf, typ.Elem())
func (w *Walker) walkFile(file *ast.File) {
// Not entering a scope here; file boundaries aren't interesting.
for _, di := range file.Decls {
switch d := di.(type) {
case *ast.GenDecl:
switch d.Tok {
case token.IMPORT:
for _, sp := range d.Specs {
is := sp.(*ast.ImportSpec)
fpath, err := strconv.Unquote(is.Path.Value)
if err != nil {
log.Fatal(err)
}
name := path.Base(fpath)
if is.Name != nil {
name = is.Name.Name
}
w.selectorFullPkg[name] = fpath
}
case token.CONST:
for _, sp := range d.Specs {
w.walkConst(sp.(*ast.ValueSpec))
}
case token.TYPE:
for _, sp := range d.Specs {
w.walkTypeSpec(sp.(*ast.TypeSpec))
}
case token.VAR:
for _, sp := range d.Specs {
w.walkVar(sp.(*ast.ValueSpec))
}
default:
log.Fatalf("unknown token type %d in GenDecl", d.Tok)
}
case *ast.FuncDecl:
// Ignore. Handled in subsequent pass, by go/doc.
default:
log.Printf("unhandled %T, %#v\n", di, di)
printer.Fprint(os.Stderr, fset, di)
os.Stderr.Write([]byte("\n"))
case *types.Named:
obj := typ.Obj()
pkg := obj.Pkg()
if pkg != nil && pkg != w.current {
buf.WriteString(pkg.Name())
buf.WriteByte('.')
}
}
}
buf.WriteString(typ.Obj().Name())
var constType = map[token.Token]string{
token.INT: "ideal-int",
token.FLOAT: "ideal-float",
token.STRING: "ideal-string",
token.CHAR: "ideal-char",
token.IMAG: "ideal-imag",
default:
panic(fmt.Sprintf("unknown type %T", typ))
}
}
var varType = map[token.Token]string{
token.INT: "int",
token.FLOAT: "float64",
token.STRING: "string",
token.CHAR: "rune",
token.IMAG: "complex128",
func (w *Walker) writeSignature(buf *bytes.Buffer, sig *types.Signature) {
w.writeParams(buf, sig.Params(), sig.IsVariadic())
switch res := sig.Results(); res.Len() {
case 0:
// nothing to do
case 1:
buf.WriteByte(' ')
w.writeType(buf, res.At(0).Type())
default:
buf.WriteByte(' ')
w.writeParams(buf, res, false)
}
}
var errTODO = errors.New("TODO")
func (w *Walker) constValueType(vi interface{}) (string, error) {
switch v := vi.(type) {
case *ast.BasicLit:
litType, ok := constType[v.Kind]
if !ok {
return "", fmt.Errorf("unknown basic literal kind %#v", v)
}
return litType, nil
case *ast.UnaryExpr:
return w.constValueType(v.X)
case *ast.SelectorExpr:
lhs := w.nodeString(v.X)
rhs := w.nodeString(v.Sel)
pkg, ok := w.selectorFullPkg[lhs]
if !ok {
return "", fmt.Errorf("unknown constant reference; unknown package in expression %s.%s", lhs, rhs)
}
if t, ok := w.prevConstType[pkgSymbol{pkg, rhs}]; ok {
return t, nil
}
return "", fmt.Errorf("unknown constant reference to %s.%s", lhs, rhs)
case *ast.Ident:
if v.Name == "iota" {
return "ideal-int", nil // hack.
}
if v.Name == "false" || v.Name == "true" {
return "bool", nil
}
if v.Name == "intSize" && w.curPackageName == "strconv" {
// Hack.
return "ideal-int", nil
}
if t, ok := w.prevConstType[pkgSymbol{w.curPackageName, v.Name}]; ok {
return t, nil
}
return constDepPrefix + v.Name, nil
case *ast.BinaryExpr:
switch v.Op {
case token.EQL, token.LSS, token.GTR, token.NOT, token.NEQ, token.LEQ, token.GEQ:
return "bool", nil
}
left, err := w.constValueType(v.X)
if err != nil {
return "", err
func (w *Walker) writeParams(buf *bytes.Buffer, t *types.Tuple, variadic bool) {
buf.WriteByte('(')
for i, n := 0, t.Len(); i < n; i++ {
if i > 0 {
buf.WriteString(", ")
}
right, err := w.constValueType(v.Y)
if err != nil {
return "", err
typ := t.At(i).Type()
if variadic && i+1 == n {
buf.WriteString("...")
typ = typ.(*types.Slice).Elem()
}
if left != right {
// TODO(bradfitz): encode the real rules here,
// rather than this mess.
if left == "ideal-int" && right == "ideal-float" {
return "ideal-float", nil // math.Log2E
}
if left == "ideal-char" && right == "ideal-int" {
return "ideal-int", nil // math/big.MaxBase
}
if left == "ideal-int" && right == "ideal-char" {
return "ideal-int", nil // text/scanner.GoWhitespace
}
if left == "ideal-int" && right == "Duration" {
// Hack, for package time.
return "Duration", nil
}
if left == "ideal-int" && !strings.HasPrefix(right, "ideal-") {
return right, nil
}
if right == "ideal-int" && !strings.HasPrefix(left, "ideal-") {
return left, nil
}
if strings.HasPrefix(left, constDepPrefix) && strings.HasPrefix(right, constDepPrefix) {
// Just pick one.
// e.g. text/scanner GoTokens const-dependency:ScanIdents, const-dependency:ScanFloats
return left, nil
}
return "", fmt.Errorf("in BinaryExpr, unhandled type mismatch; left=%q, right=%q", left, right)
}
return left, nil
case *ast.CallExpr:
// Not a call, but a type conversion.
return w.nodeString(v.Fun), nil
case *ast.ParenExpr:
return w.constValueType(v.X)
w.writeType(buf, typ)
}
return "", fmt.Errorf("unknown const value type %T", vi)
buf.WriteByte(')')
}
func (w *Walker) varValueType(vi interface{}) (string, error) {
switch v := vi.(type) {
case *ast.BasicLit:
litType, ok := varType[v.Kind]
if !ok {
return "", fmt.Errorf("unknown basic literal kind %#v", v)
}
return litType, nil
case *ast.CompositeLit:
return w.nodeString(v.Type), nil
case *ast.FuncLit:
return w.nodeString(w.namelessType(v.Type)), nil
case *ast.UnaryExpr:
if v.Op == token.AND {
typ, err := w.varValueType(v.X)
return "*" + typ, err
}
return "", fmt.Errorf("unknown unary expr: %#v", v)
case *ast.SelectorExpr:
return "", errTODO
case *ast.Ident:
node, _, ok := w.resolveName(v.Name)
if !ok {
return "", fmt.Errorf("unresolved identifier: %q", v.Name)
}
return w.varValueType(node)
case *ast.BinaryExpr:
left, err := w.varValueType(v.X)
if err != nil {
return "", err
}
right, err := w.varValueType(v.Y)
if err != nil {
return "", err
}
if left != right {
return "", fmt.Errorf("in BinaryExpr, unhandled type mismatch; left=%q, right=%q", left, right)
}
return left, nil
case *ast.ParenExpr:
return w.varValueType(v.X)
case *ast.CallExpr:
var funSym pkgSymbol
if selnode, ok := v.Fun.(*ast.SelectorExpr); ok {
// assume it is not a method.
pkg, ok := w.selectorFullPkg[w.nodeString(selnode.X)]
if !ok {
return "", fmt.Errorf("not a package: %s", w.nodeString(selnode.X))
}
funSym = pkgSymbol{pkg, selnode.Sel.Name}
if retType, ok := w.functionTypes[funSym]; ok {
if ast.IsExported(retType) && pkg != w.curPackageName {
// otherpkg.F returning an exported type from otherpkg.
return pkg + "." + retType, nil
} else {
return retType, nil
}
}
} else {
funSym = pkgSymbol{w.curPackageName, w.nodeString(v.Fun)}
if retType, ok := w.functionTypes[funSym]; ok {
return retType, nil
}
}
// maybe a function call; maybe a conversion. Need to lookup type.
// TODO(bradfitz): this is a hack, but arguably most of this tool is,
// until the Go AST has type information.
nodeStr := w.nodeString(v.Fun)
switch nodeStr {
case "string", "[]byte":
return nodeStr, nil
}
return "", fmt.Errorf("not a known function %q", nodeStr)
default:
return "", fmt.Errorf("unknown const value type %T", vi)
}
func (w *Walker) typeString(typ types.Type) string {
var buf bytes.Buffer
w.writeType(&buf, typ)
return buf.String()
}
// resolveName finds a top-level node named name and returns the node
// v and its type t, if known.
func (w *Walker) resolveName(name string) (v interface{}, t interface{}, ok bool) {
for _, file := range w.curPackage.Files {
for _, di := range file.Decls {
switch d := di.(type) {
case *ast.GenDecl:
switch d.Tok {
case token.VAR:
for _, sp := range d.Specs {
vs := sp.(*ast.ValueSpec)
for i, vname := range vs.Names {
if vname.Name == name {
if len(vs.Values) > i {
return vs.Values[i], vs.Type, true
}
return nil, vs.Type, true
}
}
}
}
}
}
}
return nil, nil, false
func (w *Walker) signatureString(sig *types.Signature) string {
var buf bytes.Buffer
w.writeSignature(&buf, sig)
return buf.String()
}
// constDepPrefix is a magic prefix that is used by constValueType
// and walkConst to signal that a type isn't known yet. These are
// resolved at the end of walking of a package's files.
const constDepPrefix = "const-dependency:"
func (w *Walker) emitObj(obj types.Object) {
switch obj := obj.(type) {
case *types.Const:
w.emitf("const %s %s", obj.Name(), w.typeString(obj.Type()))
func (w *Walker) walkConst(vs *ast.ValueSpec) {
for _, ident := range vs.Names {
litType := ""
if vs.Type != nil {
litType = w.nodeString(vs.Type)
} else {
litType = w.lastConstType
if vs.Values != nil {
if len(vs.Values) != 1 {
log.Fatalf("const %q, values: %#v", ident.Name, vs.Values)
}
var err error
litType, err = w.constValueType(vs.Values[0])
if err != nil {
log.Fatalf("unknown kind in const %q (%T): %v", ident.Name, vs.Values[0], err)
}
}
}
if dep := strings.TrimPrefix(litType, constDepPrefix); dep != litType {
w.constDep[ident.Name] = dep
continue
}
if litType == "" {
log.Fatalf("unknown kind in const %q", ident.Name)
}
w.lastConstType = litType
case *types.Var:
w.emitf("var %s %s", obj.Name(), w.typeString(obj.Type()))
w.prevConstType[pkgSymbol{w.curPackageName, ident.Name}] = litType
case *types.TypeName:
w.emitType(obj)
if ast.IsExported(ident.Name) {
w.emitFeature(fmt.Sprintf("const %s %s", ident, litType))
}
}
}
case *types.Func:
w.emitFunc(obj)
func (w *Walker) resolveConstantDeps() {
var findConstType func(string) string
findConstType = func(ident string) string {
if dep, ok := w.constDep[ident]; ok {
return findConstType(dep)
}
if t, ok := w.prevConstType[pkgSymbol{w.curPackageName, ident}]; ok {
return t
}
return ""
}
for ident := range w.constDep {
if !ast.IsExported(ident) {
continue
}
t := findConstType(ident)
if t == "" {
log.Fatalf("failed to resolve constant %q", ident)
}
w.emitFeature(fmt.Sprintf("const %s %s", ident, t))
default:
panic("unknown object: " + obj.String())
}
}
func (w *Walker) walkVar(vs *ast.ValueSpec) {
for i, ident := range vs.Names {
if !ast.IsExported(ident.Name) {
continue
}
func (w *Walker) emitType(obj *types.TypeName) {
name := obj.Name()
typ := obj.Type()
switch typ := typ.Underlying().(type) {
case *types.Struct:
w.emitStructType(name, typ)
case *types.Interface:
w.emitIfaceType(name, typ)
return // methods are handled by emitIfaceType
default:
w.emitf("type %s %s", name, w.typeString(typ.Underlying()))
}
typ := ""
if vs.Type != nil {
typ = w.nodeString(vs.Type)
} else {
if len(vs.Values) == 0 {
log.Fatalf("no values for var %q", ident.Name)
}
if len(vs.Values) > 1 {
log.Fatalf("more than 1 values in ValueSpec not handled, var %q", ident.Name)
}
var err error
typ, err = w.varValueType(vs.Values[i])
if err != nil {
log.Fatalf("unknown type of variable %q, type %T, error = %v\ncode: %s",
ident.Name, vs.Values[i], err, w.nodeString(vs.Values[i]))
// emit methods with value receiver
var methodNames map[string]bool
vset := typ.MethodSet()
for i, n := 0, vset.Len(); i < n; i++ {
m := vset.At(i)
if m.Obj().IsExported() {
w.emitMethod(m)
if methodNames == nil {
methodNames = make(map[string]bool)
}
methodNames[m.Obj().Name()] = true
}
w.emitFeature(fmt.Sprintf("var %s %s", ident, typ))
}
}
func (w *Walker) nodeString(node interface{}) string {
if node == nil {
return ""
}
var b bytes.Buffer
printer.Fprint(&b, fset, node)
return b.String()
}
func (w *Walker) nodeDebug(node interface{}) string {
if node == nil {
return ""
}
var b bytes.Buffer
ast.Fprint(&b, fset, node, nil)
return b.String()
}
func (w *Walker) noteInterface(name string, it *ast.InterfaceType) {
w.interfaces[pkgSymbol{w.curPackageName, name}] = it
}
func (w *Walker) walkTypeSpec(ts *ast.TypeSpec) {
name := ts.Name.Name
if !ast.IsExported(name) {
return
}
switch t := ts.Type.(type) {
case *ast.StructType:
w.walkStructType(name, t)
case *ast.InterfaceType:
w.walkInterfaceType(name, t)
default:
w.emitFeature(fmt.Sprintf("type %s %s", name, w.nodeString(w.namelessType(ts.Type))))
// emit methods with pointer receiver; exclude
// methods that we have emitted already
// (the method set of *T includes the methods of T)
pset := types.NewPointer(typ).MethodSet()
for i, n := 0, pset.Len(); i < n; i++ {
m := pset.At(i)
if m.Obj().IsExported() && !methodNames[m.Obj().Name()] {
w.emitMethod(m)
}
}
}
func (w *Walker) walkStructType(name string, t *ast.StructType) {
func (w *Walker) emitStructType(name string, typ *types.Struct) {
typeStruct := fmt.Sprintf("type %s struct", name)
w.emitFeature(typeStruct)
pop := w.pushScope(typeStruct)
defer pop()
for _, f := range t.Fields.List {
typ := f.Type
for _, name := range f.Names {
if ast.IsExported(name.Name) {
w.emitFeature(fmt.Sprintf("%s %s", name, w.nodeString(w.namelessType(typ))))
}
w.emitf(typeStruct)
defer w.pushScope(typeStruct)()
for i := 0; i < typ.NumFields(); i++ {
f := typ.Field(i)
if !f.IsExported() {
continue
}
if f.Names == nil {
switch v := typ.(type) {
case *ast.Ident:
if ast.IsExported(v.Name) {
w.emitFeature(fmt.Sprintf("embedded %s", v.Name))
}
case *ast.StarExpr:
switch vv := v.X.(type) {
case *ast.Ident:
if ast.IsExported(vv.Name) {
w.emitFeature(fmt.Sprintf("embedded *%s", vv.Name))
}
case *ast.SelectorExpr:
w.emitFeature(fmt.Sprintf("embedded %s", w.nodeString(typ)))
default:
log.Fatalf("unable to handle embedded starexpr before %T", typ)
}
case *ast.SelectorExpr:
w.emitFeature(fmt.Sprintf("embedded %s", w.nodeString(typ)))
default:
log.Fatalf("unable to handle embedded %T", typ)
}
typ := f.Type()
if f.Anonymous() {
w.emitf("embedded %s", w.typeString(typ))
continue
}
w.emitf("%s %s", f.Name(), w.typeString(typ))
}
}
// method is a method of an interface.
type method struct {
name string // "Read"
sig string // "([]byte) (int, error)", from funcSigString
}
// interfaceMethods returns the expanded list of exported methods for an interface.
// The boolean complete reports whether the list contains all methods (that is, the
// interface has no unexported methods).
// pkg is the complete package name ("net/http")
// iname is the interface name.
func (w *Walker) interfaceMethods(pkg, iname string) (methods []method, complete bool) {
t, ok := w.interfaces[pkgSymbol{pkg, iname}]
if !ok {
log.Fatalf("failed to find interface %s.%s", pkg, iname)
}
func (w *Walker) emitIfaceType(name string, typ *types.Interface) {
pop := w.pushScope("type " + name + " interface")
complete = true
for _, f := range t.Methods.List {
typ := f.Type
switch tv := typ.(type) {
case *ast.FuncType:
for _, mname := range f.Names {
if ast.IsExported(mname.Name) {
ft := typ.(*ast.FuncType)
methods = append(methods, method{
name: mname.Name,
sig: w.funcSigString(ft),
})
} else {
complete = false
}
}
case *ast.Ident:
embedded := typ.(*ast.Ident).Name
if embedded == "error" {
methods = append(methods, method{
name: "Error",
sig: "() string",
})
continue
}
if !ast.IsExported(embedded) {
log.Fatalf("unexported embedded interface %q in exported interface %s.%s; confused",
embedded, pkg, iname)
}
m, c := w.interfaceMethods(pkg, embedded)
methods = append(methods, m...)
complete = complete && c
case *ast.SelectorExpr:
lhs := w.nodeString(tv.X)
rhs := w.nodeString(tv.Sel)
fpkg, ok := w.selectorFullPkg[lhs]
if !ok {
log.Fatalf("can't resolve selector %q in interface %s.%s", lhs, pkg, iname)
}
m, c := w.interfaceMethods(fpkg, rhs)
methods = append(methods, m...)
complete = complete && c
default:
log.Fatalf("unknown type %T in interface field", typ)
var methodNames []string
complete := true
mset := typ.MethodSet()
for i, n := 0, mset.Len(); i < n; i++ {
m := mset.At(i).Obj().(*types.Func)
if !m.IsExported() {
complete = false
continue
}
methodNames = append(methodNames, m.Name())
w.emitf("%s%s", m.Name(), w.signatureString(m.Type().(*types.Signature)))
}
return
}
func (w *Walker) walkInterfaceType(name string, t *ast.InterfaceType) {
methNames := []string{}
pop := w.pushScope("type " + name + " interface")
methods, complete := w.interfaceMethods(w.curPackageName, name)
for _, m := range methods {
methNames = append(methNames, m.name)
w.emitFeature(fmt.Sprintf("%s%s", m.name, m.sig))
}
if !complete {
// The method set has unexported methods, so all the
// implementations are provided by the same package,
// so the method set can be extended. Instead of recording
// the full set of names (below), record only that there were
// unexported methods. (If the interface shrinks, we will notice
// because a method signature emitted during the last loop,
// because a method signature emitted during the last loop
// will disappear.)
w.emitFeature("unexported methods")
w.emitf("unexported methods")
}
pop()
if !complete {
return
}
sort.Strings(methNames)
if len(methNames) == 0 {
w.emitFeature(fmt.Sprintf("type %s interface {}", name))
} else {
w.emitFeature(fmt.Sprintf("type %s interface { %s }", name, strings.Join(methNames, ", ")))
}
}
func (w *Walker) peekFuncDecl(f *ast.FuncDecl) {
if f.Recv != nil {
if len(methodNames) == 0 {
w.emitf("type %s interface {}", name)
return
}
// Record return type for later use.
if f.Type.Results != nil && len(f.Type.Results.List) == 1 {
retType := w.nodeString(w.namelessType(f.Type.Results.List[0].Type))
w.functionTypes[pkgSymbol{w.curPackageName, f.Name.Name}] = retType
}
}
func (w *Walker) walkFuncDecl(f *ast.FuncDecl) {
if !ast.IsExported(f.Name.Name) {
return
}
if f.Recv != nil {
// Method.
recvType := w.nodeString(f.Recv.List[0].Type)
keep := ast.IsExported(recvType) ||
(strings.HasPrefix(recvType, "*") &&
ast.IsExported(recvType[1:]))
if !keep {
return
}
w.emitFeature(fmt.Sprintf("method (%s) %s%s", recvType, f.Name.Name, w.funcSigString(f.Type)))
return
}
// Else, a function
w.emitFeature(fmt.Sprintf("func %s%s", f.Name.Name, w.funcSigString(f.Type)))
}
func (w *Walker) funcSigString(ft *ast.FuncType) string {
var b bytes.Buffer
writeField := func(b *bytes.Buffer, f *ast.Field) {
if n := len(f.Names); n > 1 {
for i := 0; i < n; i++ {
if i > 0 {
b.WriteString(", ")
}
b.WriteString(w.nodeString(w.namelessType(f.Type)))
}
} else {
b.WriteString(w.nodeString(w.namelessType(f.Type)))
}
}
b.WriteByte('(')
if ft.Params != nil {
for i, f := range ft.Params.List {
if i > 0 {
b.WriteString(", ")
}
writeField(&b, f)
}
}
b.WriteByte(')')
if ft.Results != nil {
nr := 0
for _, f := range ft.Results.List {
if n := len(f.Names); n > 1 {
nr += n
} else {
nr++
}
}
if nr > 0 {
b.WriteByte(' ')
if nr > 1 {
b.WriteByte('(')
}
for i, f := range ft.Results.List {
if i > 0 {
b.WriteString(", ")
}
writeField(&b, f)
}
if nr > 1 {
b.WriteByte(')')
}
}
}
return b.String()
sort.Strings(methodNames)
w.emitf("type %s interface { %s }", name, strings.Join(methodNames, ", "))
}
// namelessType returns a type node that lacks any variable names.
func (w *Walker) namelessType(t interface{}) interface{} {
ft, ok := t.(*ast.FuncType)
if !ok {
return t
}
return &ast.FuncType{
Params: w.namelessFieldList(ft.Params),
Results: w.namelessFieldList(ft.Results),
func (w *Walker) emitFunc(f *types.Func) {
sig := f.Type().(*types.Signature)
if sig.Recv() != nil {
panic("method considered a regular function: " + f.String())
}
w.emitf("func %s%s", f.Name(), w.signatureString(sig))
}
// namelessFieldList returns a deep clone of fl, with the cloned fields
// lacking names.
func (w *Walker) namelessFieldList(fl *ast.FieldList) *ast.FieldList {
fl2 := &ast.FieldList{}
if fl != nil {
for _, f := range fl.List {
repeats := 1
if len(f.Names) > 1 {
repeats = len(f.Names)
}
for i := 0; i < repeats; i++ {
fl2.List = append(fl2.List, w.namelessField(f))
}
func (w *Walker) emitMethod(m *types.Selection) {
sig := m.Type().(*types.Signature)
recv := sig.Recv().Type()
// report exported methods with unexported reveiver base type
if true {
base := recv
if p, _ := recv.(*types.Pointer); p != nil {
base = p.Elem()
}
if obj := base.(*types.Named).Obj(); !obj.IsExported() {
log.Fatalf("exported method with unexported receiver base type: %s", m)
}
}
return fl2
w.emitf("method (%s) %s%s", w.typeString(recv), m.Obj().Name(), w.signatureString(sig))
}
// namelessField clones f, but not preserving the names of fields.
// (comments and tags are also ignored)
func (w *Walker) namelessField(f *ast.Field) *ast.Field {
return &ast.Field{
Type: f.Type,
func (w *Walker) emitf(format string, args ...interface{}) {
f := strings.Join(w.scope, ", ") + ", " + fmt.Sprintf(format, args...)
if strings.Contains(f, "\n") {
panic("feature contains newlines: " + f)
}
}
var (
byteRx = regexp.MustCompile(`\bbyte\b`)
runeRx = regexp.MustCompile(`\brune\b`)
)
func (w *Walker) emitFeature(feature string) {
if !w.wantedPkg[w.curPackageName] {
return
}
if strings.Contains(feature, "byte") {
feature = byteRx.ReplaceAllString(feature, "uint8")
}
if strings.Contains(feature, "rune") {
feature = runeRx.ReplaceAllString(feature, "int32")
}
f := strings.Join(w.scope, ", ") + ", " + feature
if _, dup := w.features[f]; dup {
panic("duplicate feature inserted: " + f)
}
if strings.Contains(f, "\n") {
// TODO: for now, just skip over the
// runtime.MemStatsType.BySize type, which this tool
// doesn't properly handle. It's pretty low-level,
// though, so not super important to protect against.
if strings.HasPrefix(f, "pkg runtime") && strings.Contains(f, "BySize [61]struct") {
return
}
panic("feature contains newlines: " + f)
}
w.features[f] = true
if *verbose {
log.Printf("feature: %s", f)
}
}
func strListContains(l []string, s string) bool {
for _, v := range l {
if v == s {
return true
}
}
return false
}
// +build api_tool
// Copyright 2011 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.
......@@ -33,12 +35,10 @@ func TestGolden(t *testing.T) {
if !fi.IsDir() {
continue
}
w := NewWalker()
w.wantedPkg[fi.Name()] = true
w.root = "testdata/src/pkg"
goldenFile := filepath.Join("testdata", "src", "pkg", fi.Name(), "golden.txt")
w.WalkPackage(fi.Name())
w := NewWalker(nil, "testdata/src/pkg")
w.export(w.Import(fi.Name()))
if *updateGolden {
os.Remove(goldenFile)
......
pkg p1, const A ideal-int
pkg p1, const A64 int64
pkg p1, const AIsLowerA ideal-int
pkg p1, const B ideal-int
pkg p1, const B0 ideal-int
pkg p1, const ConstChase2 ideal-int
pkg p1, const ConversionConst MyInt
pkg p1, const FloatConst ideal-float
......@@ -10,6 +10,7 @@ pkg p1, func Bar(int8, int16, int64)
pkg p1, func Bar1(int8, int16, int64) uint64
pkg p1, func Bar2(int8, int16, int64) (uint8, uint64)
pkg p1, func BarE() Error
pkg p1, func Now() Time
pkg p1, func PlainFunc(int, int, string) (*B, error)
pkg p1, func TakesFunc(func(int) int)
pkg p1, method (*B) JustOnB()
......@@ -34,9 +35,9 @@ pkg p1, type ByteStruct struct, R int32
pkg p1, type Codec struct
pkg p1, type Codec struct, Func func(int, int) int
pkg p1, type EmbedSelector struct
pkg p1, type EmbedSelector struct, embedded time.Time
pkg p1, type EmbedSelector struct, embedded Time
pkg p1, type EmbedURLPtr struct
pkg p1, type EmbedURLPtr struct, embedded *url.URL
pkg p1, type EmbedURLPtr struct, embedded *URL
pkg p1, type Embedded struct
pkg p1, type Error interface { Error, Temporary }
pkg p1, type Error interface, Error() string
......@@ -58,7 +59,7 @@ pkg p1, type Public interface, X()
pkg p1, type Public interface, Y()
pkg p1, type S struct
pkg p1, type S struct, Public *int
pkg p1, type S struct, PublicTime time.Time
pkg p1, type S struct, PublicTime Time
pkg p1, type S2 struct
pkg p1, type S2 struct, Extra bool
pkg p1, type S2 struct, embedded S
......@@ -68,6 +69,8 @@ pkg p1, type T struct
pkg p1, type TPtrExported struct
pkg p1, type TPtrExported struct, embedded *Embedded
pkg p1, type TPtrUnexported struct
pkg p1, type Time struct
pkg p1, type URL struct
pkg p1, var Byte uint8
pkg p1, var ByteConv []uint8
pkg p1, var ByteFunc func(uint8) int32
......@@ -81,5 +84,5 @@ pkg p1, var V1 uint64
pkg p1, var V2 p2.Twoer
pkg p1, var VError Error
pkg p1, var X I
pkg p1, var X int64
pkg p1, var X0 int64
pkg p1, var Y int
......@@ -35,7 +35,7 @@ var (
var ChecksumError = ptwo.NewError("gzip checksum error")
const B = 2
const B0 = 2
const StrConst = "foo"
const FloatConst = 1.5
......@@ -43,14 +43,18 @@ type myInt int
type MyInt int
type Time struct{}
type S struct {
Public *int
private *int
PublicTime time.Time
PublicTime Time
}
type URL struct{}
type EmbedURLPtr struct {
*url.URL
*URL
}
type S2 struct {
......@@ -58,7 +62,7 @@ type S2 struct {
Extra bool
}
var X int64
var X0 int64
var (
Y int
......@@ -163,7 +167,7 @@ func (*common) OnBothTandBPtr() {}
func (common) OnBothTandBVal() {}
type EmbedSelector struct {
time.Time
Time
}
const (
......@@ -174,10 +178,15 @@ const (
func ellipsis(...string) {}
func Now() Time {
var now Time
return now
}
var x = &S{
Public: nil,
private: nil,
publicTime: time.Now(),
PublicTime: Now(),
}
var parenExpr = (1 + 5)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment