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