gotypes: doc exported symbols (#9)
This commit is contained in:
@@ -10,24 +10,35 @@ import (
|
|||||||
"github.com/mmcloughlin/avo/operand"
|
"github.com/mmcloughlin/avo/operand"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Sizes provides type sizes used by the standard Go compiler on amd64.
|
||||||
var Sizes = types.SizesFor("gc", "amd64")
|
var Sizes = types.SizesFor("gc", "amd64")
|
||||||
|
|
||||||
|
// Basic represents a primitive/basic type at a given memory address.
|
||||||
type Basic struct {
|
type Basic struct {
|
||||||
Addr operand.Mem
|
Addr operand.Mem
|
||||||
Type *types.Basic
|
Type *types.Basic
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Component provides access to sub-components of a Go type.
|
||||||
type Component interface {
|
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)
|
Resolve() (*Basic, error)
|
||||||
Base() Component
|
|
||||||
Len() Component
|
Base() Component // base pointer of a string or slice
|
||||||
Cap() Component
|
Len() Component // length of a string or slice
|
||||||
Real() Component
|
Cap() Component // capacity of a slice
|
||||||
Imag() Component
|
Real() Component // real part of a complex value
|
||||||
Index(int) Component
|
Imag() Component // imaginary part of a complex value
|
||||||
Field(string) Component
|
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
|
type componenterr string
|
||||||
|
|
||||||
func errorf(format string, args ...interface{}) Component {
|
func errorf(format string, args ...interface{}) Component {
|
||||||
@@ -50,6 +61,7 @@ type component struct {
|
|||||||
offset int
|
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 {
|
func NewComponent(name string, t types.Type, offset int) Component {
|
||||||
return &component{
|
return &component{
|
||||||
name: name,
|
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) {
|
func (c *component) Resolve() (*Basic, error) {
|
||||||
b := toprimitive(c.typ)
|
b := toprimitive(c.typ)
|
||||||
if b == nil {
|
if b == nil {
|
||||||
|
|||||||
2
gotypes/doc.go
Normal file
2
gotypes/doc.go
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
// Package gotypes provides helpers for interacting with Go types within avo functions.
|
||||||
|
package gotypes
|
||||||
16
gotypes/examples_test.go
Normal file
16
gotypes/examples_test.go
Normal file
@@ -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,6 +8,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Signature represents a Go function signature.
|
||||||
type Signature struct {
|
type Signature struct {
|
||||||
pkg *types.Package
|
pkg *types.Package
|
||||||
sig *types.Signature
|
sig *types.Signature
|
||||||
@@ -15,6 +16,7 @@ type Signature struct {
|
|||||||
results *Tuple
|
results *Tuple
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewSignature constructs a Signature.
|
||||||
func NewSignature(pkg *types.Package, sig *types.Signature) *Signature {
|
func NewSignature(pkg *types.Package, sig *types.Signature) *Signature {
|
||||||
s := &Signature{
|
s := &Signature{
|
||||||
pkg: pkg,
|
pkg: pkg,
|
||||||
@@ -24,14 +26,20 @@ func NewSignature(pkg *types.Package, sig *types.Signature) *Signature {
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewSignatureVoid builds the void signature "func()".
|
||||||
func NewSignatureVoid() *Signature {
|
func NewSignatureVoid() *Signature {
|
||||||
return NewSignature(nil, types.NewSignature(nil, nil, nil, false))
|
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) {
|
func ParseSignature(expr string) (*Signature, error) {
|
||||||
return ParseSignatureInPackage(nil, expr)
|
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) {
|
func ParseSignatureInPackage(pkg *types.Package, expr string) (*Signature, error) {
|
||||||
tv, err := types.Eval(token.NewFileSet(), pkg, token.NoPos, expr)
|
tv, err := types.Eval(token.NewFileSet(), pkg, token.NoPos, expr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -47,12 +55,16 @@ func ParseSignatureInPackage(pkg *types.Package, expr string) (*Signature, error
|
|||||||
return NewSignature(pkg, s), nil
|
return NewSignature(pkg, s), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Params returns the function signature argument types.
|
||||||
func (s *Signature) Params() *Tuple { return s.params }
|
func (s *Signature) Params() *Tuple { return s.params }
|
||||||
|
|
||||||
|
// Results returns the function return types.
|
||||||
func (s *Signature) Results() *Tuple { return s.results }
|
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() }
|
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 {
|
func (s *Signature) String() string {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
types.WriteSignature(&buf, s.sig, types.RelativeTo(s.pkg))
|
types.WriteSignature(&buf, s.sig, types.RelativeTo(s.pkg))
|
||||||
@@ -83,6 +95,7 @@ func (s *Signature) init() {
|
|||||||
s.results = newTuple(r, resultsoffsets, resultssize, "ret")
|
s.results = newTuple(r, resultsoffsets, resultssize, "ret")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tuple represents a tuple of variables, such as function arguments or results.
|
||||||
type Tuple struct {
|
type Tuple struct {
|
||||||
components []Component
|
components []Component
|
||||||
byname map[string]Component
|
byname map[string]Component
|
||||||
@@ -112,6 +125,7 @@ func newTuple(t *types.Tuple, offsets []int64, size int64, defaultprefix string)
|
|||||||
return tuple
|
return tuple
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lookup returns the variable with the given name.
|
||||||
func (t *Tuple) Lookup(name string) Component {
|
func (t *Tuple) Lookup(name string) Component {
|
||||||
e := t.byname[name]
|
e := t.byname[name]
|
||||||
if e == nil {
|
if e == nil {
|
||||||
@@ -120,6 +134,7 @@ func (t *Tuple) Lookup(name string) Component {
|
|||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// At returns the variable at index i.
|
||||||
func (t *Tuple) At(i int) Component {
|
func (t *Tuple) At(i int) Component {
|
||||||
if i >= len(t.components) {
|
if i >= len(t.components) {
|
||||||
return errorf("index out of range")
|
return errorf("index out of range")
|
||||||
@@ -127,6 +142,7 @@ func (t *Tuple) At(i int) Component {
|
|||||||
return t.components[i]
|
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 (t *Tuple) Bytes() int { return t.size }
|
||||||
|
|
||||||
func tuplevars(t *types.Tuple) []*types.Var {
|
func tuplevars(t *types.Tuple) []*types.Var {
|
||||||
|
|||||||
Reference in New Issue
Block a user