README

##What’s this?

Typewriter is a package to enable pluggable, type-driven codegen for Go. The envisioned use case is for generics-like functionality. This package forms the underpinning of gen.

Usage is analogous to how codecs work with Go’s image package, or database drivers in the sql package.

import (
    // main package
	“github.com/clipperhouse/typewriter”
	
	// any number of typewriters 
	_ “github.com/clipperhouse/set”
	_ “github.com/clipperhouse/linkedlist”
)

func main() {
	app, err := typewriter.NewApp(”+gen”)
	if err != nil {
        panic(err)
	}

	app.WriteAll()
}

Individual typewriters register themselves to the “parent” package via their init() functions. Have a look at one of the above typewriters to get an idea.

Documentation

Overview

The typewriter package provides a framework for type-driven code generation. It implements the core functionality of gen.

This package is primarily of interest to those who wish to extend gen with third-party functionality.

More docs are available at https://clipperhouse.github.io/gen/typewriters.

Index

Constants

This section is empty.

Variables

View Source
var DefaultConfig = &Config{}

Functions

func Register

func Register(tw Interface) error

Register allows template packages to make themselves known to a 'parent' package, usually in the init() func. Comparable to the approach taken by stdlib's image package for registration of image types (eg image/png). Your program will do something like:

import (
	"github.com/clipperhouse/typewriter"
	_ "github.com/clipperhouse/slice"
)

Types

type App

type App struct {
	// All typewriter.Package found in the current directory.
	Packages []*Package
	// All typewriter.Interface's registered on init.
	TypeWriters []Interface
	Directive   string
}

App is the high-level construct for package-level code generation. Typical usage is along the lines of:

app, err := typewriter.NewApp()
err := app.WriteAll()

+test foo:"Bar" baz:"qux[struct{}],thing"

func NewApp

func NewApp(directive string) (*App, error)

NewApp parses the current directory, enumerating registered TypeWriters and collecting Types and their related information.

func NewAppFiltered

func NewAppFiltered(directive string, filter func(os.FileInfo) bool) (*App, error)

NewAppFiltered parses the current directory, collecting Types and their related information. Pass a filter to limit which files are operated on.

func (*App) WriteAll

func (a *App) WriteAll() ([]string, error)

WriteAll writes the generated code for all Types and TypeWriters in the App to respective files.

type Config

type Config struct {
	Filter                func(os.FileInfo) bool
	IgnoreTypeCheckErrors bool
}

func (*Config) NewApp

func (conf *Config) NewApp(directive string) (*App, error)

type Constraint

type Constraint struct {
	// A numeric type is one that supports arithmetic operations.
	Numeric bool
	// A comparable type is one that supports the == operator. Map keys must be comparable, for example.
	Comparable bool
	// An ordered type is one where greater-than and less-than are supported
	Ordered bool
}

Constraint describes type requirements.

func (Constraint) TryType

func (c Constraint) TryType(t Type) error

type ImportSpec

type ImportSpec struct {
	Name, Path string
}

ImportSpec describes the name and path of an import. The name is often omitted.

+gen set

type ImportSpecSet

type ImportSpecSet map[ImportSpec]struct{}

The primary type that represents a set

func NewImportSpecSet

func NewImportSpecSet(a ...ImportSpec) ImportSpecSet

Creates and returns a reference to an empty set.

func (ImportSpecSet) Add

func (set ImportSpecSet) Add(i ImportSpec) bool

Adds an item to the current set if it doesn't already exist in the set.

func (ImportSpecSet) Cardinality

func (set ImportSpecSet) Cardinality() int

Cardinality returns how many items are currently in the set.

func (*ImportSpecSet) Clear

func (set *ImportSpecSet) Clear()

Clears the entire set to be the empty set.

func (ImportSpecSet) Clone

func (set ImportSpecSet) Clone() ImportSpecSet

Returns a clone of the set. Does NOT clone the underlying elements.

func (ImportSpecSet) Contains

func (set ImportSpecSet) Contains(i ImportSpec) bool

Determines if a given item is already in the set.

func (ImportSpecSet) ContainsAll

func (set ImportSpecSet) ContainsAll(i ...ImportSpec) bool

Determines if the given items are all in the set

func (ImportSpecSet) Difference

func (set ImportSpecSet) Difference(other ImportSpecSet) ImportSpecSet

Returns a new set with items in the current set but not in the other set

func (ImportSpecSet) Equal

func (set ImportSpecSet) Equal(other ImportSpecSet) bool

Equal determines if two sets are equal to each other. If they both are the same size and have the same items they are considered equal. Order of items is not relevent for sets to be equal.

func (ImportSpecSet) Intersect

func (set ImportSpecSet) Intersect(other ImportSpecSet) ImportSpecSet

Returns a new set with items that exist only in both sets.

func (ImportSpecSet) IsSubset

func (set ImportSpecSet) IsSubset(other ImportSpecSet) bool

Determines if every item in the other set is in this set.

func (ImportSpecSet) IsSuperset

func (set ImportSpecSet) IsSuperset(other ImportSpecSet) bool

Determines if every item of this set is in the other set.

func (ImportSpecSet) Iter

func (set ImportSpecSet) Iter() <-chan ImportSpec

Iter() returns a channel of type ImportSpec that you can range over.

func (ImportSpecSet) Remove

func (set ImportSpecSet) Remove(i ImportSpec)

Allows the removal of a single item in the set.

func (ImportSpecSet) SymmetricDifference

func (set ImportSpecSet) SymmetricDifference(other ImportSpecSet) ImportSpecSet

Returns a new set with items in the current set or the other set but not in both.

func (ImportSpecSet) ToSlice

func (set ImportSpecSet) ToSlice() []ImportSpec

ToSlice returns the elements of the current set as a slice

func (ImportSpecSet) Union

func (set ImportSpecSet) Union(other ImportSpecSet) ImportSpecSet

Returns a new set with all items in both sets.

type Interface

type Interface interface {
	Name() string
	// Imports is a slice of imports required for the type; each will be written into the imports declaration.
	Imports(t Type) []ImportSpec
	// Write writes to the body of the generated code, following package declaration and imports.
	Write(w io.Writer, t Type) error
}

Interface is the interface to be implemented for code generation via gen

type Package

type Package struct {
	*types.Package

	Types []Type
	// contains filtered or unexported fields
}

func NewPackage

func NewPackage(path, name string) *Package

func (*Package) Eval

func (p *Package) Eval(name string) (Type, error)

type Pointer

type Pointer bool

Pointer exists as a type to allow simple use as bool or as String, which returns *

func (Pointer) String

func (p Pointer) String() string

type Tag

type Tag struct {
	Name    string
	Values  []TagValue
	Negated bool
}

+gen slice

type TagSlice

type TagSlice []Tag

TagSlice is a slice of type Tag. Use it where you would use []Tag.

type TagValue

type TagValue struct {
	Name           string
	TypeParameters []Type
	// contains filtered or unexported fields
}

type Template

type Template struct {
	Name, Text     string
	FuncMap        map[string]interface{}
	TypeConstraint Constraint
	// Indicates both the number of required type parameters, and the constraints of each (if any)
	TypeParameterConstraints []Constraint
}

Template includes the text of a template as well as requirements for the types to which it can be applied. +gen * slice:"Where"

func (*Template) Parse

func (tmpl *Template) Parse() (*template.Template, error)

Parse parses (converts) a typewriter.Template to a *template.Template

func (*Template) TryTypeAndValue

func (tmpl *Template) TryTypeAndValue(t Type, v TagValue) error

TryTypeAndValue verifies that a given Type and TagValue satisfy a Template's type constraints.

type TemplateSlice

type TemplateSlice []*Template

TemplateSlice is a slice of type *Template. Use it where you would use []*Template.

func (TemplateSlice) ByTag

func (ts TemplateSlice) ByTag(t Type, tag Tag) (*template.Template, error)

ByTag attempts to locate a template which meets type constraints, and parses it.

func (TemplateSlice) ByTagValue

func (ts TemplateSlice) ByTagValue(t Type, v TagValue) (*template.Template, error)

ByTagValue attempts to locate a template which meets type constraints, and parses it.

func (TemplateSlice) Funcs

func (ts TemplateSlice) Funcs(FuncMap map[string]interface{})

Funcs assigns non standard functions used in the template

func (TemplateSlice) Where

func (rcv TemplateSlice) Where(fn func(*Template) bool) (result TemplateSlice)

Where returns a new TemplateSlice whose elements return true for func. See: http://clipperhouse.github.io/gen/#Where

type Type

type Type struct {
	Pointer Pointer
	Name    string
	Tags    TagSlice

	types.Type
	// contains filtered or unexported fields
}

func (Type) FindTag

func (t Type) FindTag(tw Interface) (Tag, bool)

func (Type) LongName

func (t Type) LongName() string

LongName provides a name that may be useful for generated names. For example, map[string]Foo becomes MapStringFoo.

func (Type) String

func (t Type) String() (result string)

type TypeCheckError

type TypeCheckError struct {
	// contains filtered or unexported fields
}

func (*TypeCheckError) Error

func (t *TypeCheckError) Error() string