Permalink
Browse files

gotypes: doc exported symbols (#9)

  • Loading branch information...
mmcloughlin committed Jan 5, 2019
1 parent 69aeaf5 commit 52a501c7be25cfa7edaffe70f6d8e68fa15c88c0
Showing with 53 additions and 11 deletions.
  1. +19 −11 gotypes/components.go
  2. +2 −0 gotypes/doc.go
  3. +16 −0 gotypes/examples_test.go
  4. +16 −0 gotypes/signature.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 {
@@ -0,0 +1,2 @@
// Package gotypes provides helpers for interacting with Go types within avo functions.
package gotypes
@@ -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
// <nil>
}
@@ -8,13 +8,15 @@ import (
"strconv"
)

// Signature represents a Go function signature.
type Signature struct {
pkg *types.Package
sig *types.Signature
params *Tuple
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,13 +134,15 @@ 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")
}
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 {

0 comments on commit 52a501c

Please sign in to comment.