From 52a501c7be25cfa7edaffe70f6d8e68fa15c88c0 Mon Sep 17 00:00:00 2001 From: Michael McLoughlin Date: Fri, 4 Jan 2019 20:38:21 -0800 Subject: [PATCH] gotypes: doc exported symbols (#9) --- gotypes/components.go | 30 +++++++++++++++++++----------- gotypes/doc.go | 2 ++ gotypes/examples_test.go | 16 ++++++++++++++++ gotypes/signature.go | 16 ++++++++++++++++ 4 files changed, 53 insertions(+), 11 deletions(-) create mode 100644 gotypes/doc.go create mode 100644 gotypes/examples_test.go diff --git a/gotypes/components.go b/gotypes/components.go index 7c6a00e..56e0136 100644 --- a/gotypes/components.go +++ b/gotypes/components.go @@ -10,24 +10,35 @@ import ( "github.com/mmcloughlin/avo/operand" ) +// Sizes provides type sizes used by the standard Go compiler on amd64. var Sizes = types.SizesFor("gc", "amd64") +// Basic represents a primitive/basic type at a given memory address. type Basic struct { Addr operand.Mem Type *types.Basic } +// Component provides access to sub-components of a Go type. type Component interface { + // When the component has no further sub-components, Resolve will return a + // reference to the components type and memory address. If there was an error + // during any previous calls to Component methods, they will be returned at + // resolution time. Resolve() (*Basic, error) - Base() Component - Len() Component - Cap() Component - Real() Component - Imag() Component - Index(int) Component - Field(string) Component + + Base() Component // base pointer of a string or slice + Len() Component // length of a string or slice + Cap() Component // capacity of a slice + Real() Component // real part of a complex value + Imag() Component // imaginary part of a complex value + Index(int) Component // index into an array + Field(string) Component // access a struct field } +// componenterr is an error that also provides a null implementation of the +// Component interface. This enables us to return an error from Component +// methods whilst also allowing method chaining to continue. type componenterr string func errorf(format string, args ...interface{}) Component { @@ -50,6 +61,7 @@ type component struct { offset int } +// NewComponent builds a component for the named type at the given memory offset. func NewComponent(name string, t types.Type, offset int) Component { return &component{ name: name, @@ -58,10 +70,6 @@ func NewComponent(name string, t types.Type, offset int) Component { } } -func NewComponentFromVar(v *types.Var, offset int) Component { - return NewComponent(v.Name(), v.Type(), offset) -} - func (c *component) Resolve() (*Basic, error) { b := toprimitive(c.typ) if b == nil { diff --git a/gotypes/doc.go b/gotypes/doc.go new file mode 100644 index 0000000..fa8f078 --- /dev/null +++ b/gotypes/doc.go @@ -0,0 +1,2 @@ +// Package gotypes provides helpers for interacting with Go types within avo functions. +package gotypes diff --git a/gotypes/examples_test.go b/gotypes/examples_test.go new file mode 100644 index 0000000..5b9d5e3 --- /dev/null +++ b/gotypes/examples_test.go @@ -0,0 +1,16 @@ +package gotypes_test + +import ( + "fmt" + + "github.com/mmcloughlin/avo/gotypes" +) + +func ExampleParseSignature() { + s, err := gotypes.ParseSignature("func(s string, n int) string") + fmt.Println(s) + fmt.Println(err) + // Output: + // (s string, n int) string + // +} diff --git a/gotypes/signature.go b/gotypes/signature.go index fbb39b2..44a4606 100644 --- a/gotypes/signature.go +++ b/gotypes/signature.go @@ -8,6 +8,7 @@ import ( "strconv" ) +// Signature represents a Go function signature. type Signature struct { pkg *types.Package sig *types.Signature @@ -15,6 +16,7 @@ type Signature struct { results *Tuple } +// NewSignature constructs a Signature. func NewSignature(pkg *types.Package, sig *types.Signature) *Signature { s := &Signature{ pkg: pkg, @@ -24,14 +26,20 @@ func NewSignature(pkg *types.Package, sig *types.Signature) *Signature { return s } +// NewSignatureVoid builds the void signature "func()". func NewSignatureVoid() *Signature { return NewSignature(nil, types.NewSignature(nil, nil, nil, false)) } +// ParseSignature builds a Signature by parsing a Go function type expression. +// The function type must reference builtin types only; see +// ParseSignatureInPackage if custom types are required. func ParseSignature(expr string) (*Signature, error) { return ParseSignatureInPackage(nil, expr) } +// ParseSignatureInPackage builds a Signature by parsing a Go function type +// expression. The expression may reference types in the provided package. func ParseSignatureInPackage(pkg *types.Package, expr string) (*Signature, error) { tv, err := types.Eval(token.NewFileSet(), pkg, token.NoPos, expr) if err != nil { @@ -47,12 +55,16 @@ func ParseSignatureInPackage(pkg *types.Package, expr string) (*Signature, error return NewSignature(pkg, s), nil } +// Params returns the function signature argument types. func (s *Signature) Params() *Tuple { return s.params } +// Results returns the function return types. func (s *Signature) Results() *Tuple { return s.results } +// Bytes returns the total size of the function arguments and return values. func (s *Signature) Bytes() int { return s.Params().Bytes() + s.Results().Bytes() } +// String writes Signature as a string. This does not include the "func" keyword. func (s *Signature) String() string { var buf bytes.Buffer types.WriteSignature(&buf, s.sig, types.RelativeTo(s.pkg)) @@ -83,6 +95,7 @@ func (s *Signature) init() { s.results = newTuple(r, resultsoffsets, resultssize, "ret") } +// Tuple represents a tuple of variables, such as function arguments or results. type Tuple struct { components []Component byname map[string]Component @@ -112,6 +125,7 @@ func newTuple(t *types.Tuple, offsets []int64, size int64, defaultprefix string) return tuple } +// Lookup returns the variable with the given name. func (t *Tuple) Lookup(name string) Component { e := t.byname[name] if e == nil { @@ -120,6 +134,7 @@ func (t *Tuple) Lookup(name string) Component { return e } +// At returns the variable at index i. func (t *Tuple) At(i int) Component { if i >= len(t.components) { return errorf("index out of range") @@ -127,6 +142,7 @@ func (t *Tuple) At(i int) Component { return t.components[i] } +// Bytes returns the size of the Tuple. This may include additional padding. func (t *Tuple) Bytes() int { return t.size } func tuplevars(t *types.Tuple) []*types.Var {