stroo

package module
v0.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 13, 2020 License: GPL-3.0 Imports: 36 Imported by: 0

README

stroo

FOSSA Status

Ever got tired of writing a Stringer implementation over and over again? Wanted to implement Marshaler and Unmarshaler for json package?

Indeed, there are all sort of tools to generate code, but all of them are forcing you to take their own road. How about working with templates instead? Thus you could carry your template around with your project, customizing it and having no worries that the way it is being used would change.

This tool traverses Go AST using the static checker of the Go Tools. After traversal, it produces information regarding structs, functions and interfaces that are being declared in the inspected package. That information is exposed to a template that you, the developer, define. In the end, the generated code - using that template - will be written into a file of your choice.

How

Having the following declaration:

package model
//go:generate stroo -type=SomeJsonPayload -output=model_json_gen.go -template=./../../templates/json_marshal.tmpl
//go:generate stroo -type=SomeJsonPayload -output=model_json_gen.go -template=./../../templates/json_unmarshal.tmpl
type SomeJsonPayload struct{
	Name string `json:"name"`
}

stroo will use the template (relative path in the example json_marshal.tmpl and json_unmarshal.tmpl) to generate the files indicated as output, in the same package with the struct declaration.

Install

As usual, install like any other Go tool.

Playground

Yes, there is a playground to help you build templates. By default, the first type definition from the source is passed to your template and you should have at least one.

Notes

Developers can store and retrieve information inside a template : templates can store and retrieve key-values by using {{ .Store <key> <value> }} and retrieve them with {{ .Retrieve <key> }} where is a string and is interface{}.

This repository contains code taken (and modified) from internal go tools because the package is internal and cannot be imported.

Thank you good authors!

Wiki

Here is the wiki.

License

FOSSA Status

Documentation

Index

Constants

View Source
const (
	ToolName = "stroo"
)

Variables

View Source
var InvalidAnalysis = MalformedRequest{Type: Packalyse, Status: http.StatusBadRequest}
View Source
var InvalidFormat = MalformedRequest{Type: BadFormat, Status: http.StatusBadRequest}
View Source
var InvalidGoSource = MalformedRequest{Type: BadTempProject, Status: http.StatusBadRequest}
View Source
var InvalidPackage = MalformedRequest{Type: PackaLoad, Status: http.StatusBadRequest}
View Source
var InvalidTemplate = MalformedRequest{Type: TemplExe, Status: http.StatusBadRequest}
View Source
var InvalidTemplate2 = MalformedRequest{Type: TemplaParse, Status: http.StatusBadRequest}
View Source
var InvalidTypes = MalformedRequest{Type: NoTypes, Status: http.StatusBadRequest}

Functions

func DefaultAnalyzer

func DefaultAnalyzer() *analysis.Analyzer

func DefaultFuncMap

func DefaultFuncMap() template.FuncMap

func IsBasic

func IsBasic(kind string) bool

func IsComplex added in v0.0.3

func IsComplex(kind string) bool

func IsFloat added in v0.0.3

func IsFloat(kind string) bool

func IsInt added in v0.0.3

func IsInt(kind string) bool

func IsUint added in v0.0.3

func IsUint(kind string) bool

func LoadPackage

func LoadPackage(path string) (*packages.Package, error)

loads one package

func Print

func Print(analyzer *analysis.Analyzer, withRunningFolder bool) string

print the current configuration

func StartPlayground

func StartPlayground(command *Command)

Types

type Action

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

below is copy paste (with some modifications) from golang.org/x/tools/go/analysis/internal/checker, because we cannot use that internal package

func (*Action) ResultType

func (a *Action) ResultType() reflect.Type

func (*Action) String

func (a *Action) String() string

type Code

type Code struct {
	CodeConfig
	Imports     []string
	PackageInfo *PackageInfo
	// contains filtered or unexported fields
}
var Root *Code

func New

func New(
	info *PackageInfo,
	config CodeConfig,
	tmpl *template.Template,
) (*Code, error)

func (*Code) AddToImports

func (c *Code) AddToImports(imp string) string

func (*Code) DebugPrint

func (c *Code) DebugPrint() bool

func (*Code) Declare

func (c *Code) Declare(name string) error

this should be called to allow the generator to know which kind of methods we're generating

func (*Code) HasInStore

func (c *Code) HasInStore(key string) bool

func (*Code) HasNotGenerated

func (c *Code) HasNotGenerated(pkg, kind string) (bool, error)

checker for recurse generated

func (*Code) Header

func (c *Code) Header(flagValues string) string

func (*Code) Implements

func (c *Code) Implements(fieldInfo TypeInfo) (bool, error)

check if a kind has a method called the same as the template being declared

func (*Code) Keeper

func (c *Code) Keeper() map[string]interface{}

func (*Code) ListStored

func (c *Code) ListStored() []string

func (*Code) OutputFile

func (c *Code) OutputFile() string

func (*Code) PackageName

func (c *Code) PackageName() string

func (*Code) RecurseGenerate

func (c *Code) RecurseGenerate(pkg, kind string) error

uses the template name to apply the template recursively it's useful for replacing the code in existing generated files

func (*Code) ResetKeeper

func (c *Code) ResetKeeper()

func (*Code) Retrieve

func (c *Code) Retrieve(key string) (interface{}, error)

retrieves the entire "storage" at template dev disposal

func (*Code) SelectedPeerType

func (c *Code) SelectedPeerType() string

func (*Code) SelectedType

func (c *Code) SelectedType() string

getters for config - to be accessible from template

func (*Code) Serve

func (c *Code) Serve() bool

func (*Code) Store

func (c *Code) Store(key string, value interface{}) error

returns true if the key exist and will overwrite

func (*Code) StructByKey

func (c *Code) StructByKey(key string) (*TypeInfo, error)

gets a struct declaration by it's name

func (*Code) TemplateFile

func (c *Code) TemplateFile() string

func (*Code) TestMode

func (c *Code) TestMode() bool

func (*Code) Tmpl

func (c *Code) Tmpl() *template.Template

type CodeConfig

type CodeConfig struct {
	SelectedType     string
	TestMode         bool
	DebugPrint       bool
	Serve            bool
	TemplateFile     string
	TemplateName     string // keeps the name that template declares (e.g. {{ declare "String" }}) used in recurse generation and list stored
	OutputFile       string
	SelectedPeerType string
}

type Command

type Command struct {
	CodeConfig
	Inspector  *analysis.Analyzer
	WorkingDir string
	Result     *PackageInfo
	Out        bytes.Buffer
}

func NewCommand

func NewCommand(analyzer *analysis.Analyzer) *Command

builds a new command from the analyzer (which holds the inspector) and sets the Run function

func (*Command) Analyse

func (c *Command) Analyse(analyzer *analysis.Analyzer, loadedPackage *packages.Package) error

func (*Command) Generate

func (c *Command) Generate(analyzer *analysis.Analyzer) error

func (*Command) Run

func (c *Command) Run(pass *analysis.Pass) (interface{}, error)

analyzer will Run this and we're creating Package info

type ErrorType

type ErrorType int
const (
	Json           ErrorType = 1
	TemplaParse    ErrorType = 2
	BadTempProject ErrorType = 3
	PackaLoad      ErrorType = 4
	OnePackage     ErrorType = 5
	Packalyse      ErrorType = 6
	NoTypes        ErrorType = 7
	TemplExe       ErrorType = 8
	BadFormat      ErrorType = 9
)

type FunctionInfo

type FunctionInfo struct {
	Package          string
	PackagePath      string
	Name             string
	Kind             string // currently unused
	ReceiverName     string // empty for normal functions
	ReceiverType     string
	IsMethodReceiver bool
	IsExported       bool
	Params           []VarInfo
	Returns          []VarInfo
	// contains filtered or unexported fields
}

type Imports

type Imports struct {
	Name string
	Path string
}

type MalformedRequest

type MalformedRequest struct {
	Status        int       `json:"status"`
	ErrorMessage  string    `json:"errorMessage"`
	PartialSource string    `json:"partialSource"`
	Type          ErrorType `json:"type"`
}

func (MalformedRequest) Error

func (m MalformedRequest) Error() string

type Methods

type Methods []FunctionInfo

func (Methods) Len added in v0.0.3

func (s Methods) Len() int

implementation of Sorter interface, so we can sort

func (Methods) Less added in v0.0.3

func (s Methods) Less(i, j int) bool

func (Methods) Swap added in v0.0.3

func (s Methods) Swap(i, j int)

type PackageInfo

type PackageInfo struct {
	Name       string
	Path       string
	Types      TypesSlice
	Interfaces TypesSlice
	Functions  Methods
	Vars       Vars
	TypesInfo  *types.Info
	Imports    []*Imports
	PrintDebug bool
}

func (*PackageInfo) LoadImports

func (pkg *PackageInfo) LoadImports(fromImports []*types.Package)

type Tag

type Tag struct {
	Key     string   // i.e: `json:"fieldName,omitempty". Here key is: "json"
	Name    string   // i.e: `json:"fieldName,omitempty". Here name is: "fieldName"
	Options []string // `json:"fieldName,omitempty". Here options is: ["omitempty"]
}

func (*Tag) Value

func (t *Tag) Value() string

type Tags

type Tags []*Tag

func ParseTags

func ParseTags(tag string) (Tags, error)

func (Tags) Get

func (t Tags) Get(key string) (*Tag, error)

type TemporaryPackage

type TemporaryPackage struct {
	Name  string
	Files map[string]interface{}
}

type TemporaryProject

type TemporaryProject struct {
	Config      *packages.Config
	Modules     []TemporaryPackage
	TempDirName string
	// contains filtered or unexported fields
}

func CreateTempProj

func CreateTempProj(tmpPacks []TemporaryPackage) (*TemporaryProject, error)

func (*TemporaryProject) Cleanup

func (e *TemporaryProject) Cleanup()

must be called by the caller, as in `defer tmpProj.Cleanup()`

func (*TemporaryProject) File

func (e *TemporaryProject) File(tmpPackName, tmpPackFileName string) string

func (*TemporaryProject) Filename

func (e *TemporaryProject) Filename(tmpPackName, tmpPackFileName string) string

func (*TemporaryProject) Finalize

func (e *TemporaryProject) Finalize() error

type TypeInfo

type TypeInfo struct {
	Package     string            // current or imported package name
	PackagePath string            // current or imported package path
	Name        string            // for `type` in case of struct or func type declaration Name == Kind; for `field` the name of the field
	Kind        string            // for `type` usually the way we Extract; for `field` the kind of the field (for extracting `type`)
	Tags        Tags              // tags, for both
	Prefix      string            // `field` info property, for storing embedding names
	Fields      TypesSlice        // for `type` fields ; for `field` is always nil
	MethodList  Methods           // for `type` methods ; for `field` first element contains `func data` if it's marked as `IsFunc`
	IsArray     bool              // for `type` if it's array it's not a struct, it's struct; for `field` if it's an array
	IsPointer   bool              // for `type` if array, it's pointer; for `field` if it's a pointer
	IsImported  bool              // for `type` if kind it's an imported one; for `field` if it's external to current package
	IsAlias     bool              // for `type` if it's alias; for `field` it's always false
	IsFunc      bool              // for `type` if it's a function type definition; for `field`
	IsStruct    bool              // `field` info property
	IsMap       bool              // `field` info property
	IsChan      bool              // `field` info property
	IsExported  bool              // `field` info property
	IsEmbedded  bool              // `field` info property
	IsInterface bool              // `field` info property
	Comment     *ast.CommentGroup // comment found in AST
}

func NewAliasFromField

func NewAliasFromField(pkg *types.Package, field *TypeInfo, name string) TypeInfo

func (*TypeInfo) Clone added in v0.0.3

func (t *TypeInfo) Clone(newName string) TypeInfo

func (*TypeInfo) FuncData added in v0.0.3

func (t *TypeInfo) FuncData() (*FunctionInfo, error)

func (*TypeInfo) IsBasic

func (t *TypeInfo) IsBasic() bool

func (*TypeInfo) IsBool added in v0.0.3

func (t *TypeInfo) IsBool() bool

func (*TypeInfo) IsComplex added in v0.0.3

func (t *TypeInfo) IsComplex() bool

func (*TypeInfo) IsFloat added in v0.0.3

func (t *TypeInfo) IsFloat() bool

func (*TypeInfo) IsInt added in v0.0.3

func (t *TypeInfo) IsInt() bool

func (*TypeInfo) IsRune added in v0.0.3

func (t *TypeInfo) IsRune() bool

func (*TypeInfo) IsString added in v0.0.3

func (t *TypeInfo) IsString() bool

func (*TypeInfo) IsUint added in v0.0.3

func (t *TypeInfo) IsUint() bool

func (*TypeInfo) IsUnsafe added in v0.0.3

func (t *TypeInfo) IsUnsafe() bool

func (*TypeInfo) PackageAndKind added in v0.0.3

func (t *TypeInfo) PackageAndKind() string

func (*TypeInfo) RealKind added in v0.0.3

func (t *TypeInfo) RealKind() string

in case we need to print `*Something` instead of `Something`

func (*TypeInfo) SetPrefix added in v0.0.3

func (t *TypeInfo) SetPrefix(prefix string) error

func (*TypeInfo) StructOrArrayString added in v0.0.3

func (t *TypeInfo) StructOrArrayString() string

func (*TypeInfo) TagsByKey added in v0.0.3

func (t *TypeInfo) TagsByKey(name string) []string

type TypesSlice

type TypesSlice []TypeInfo

func (TypesSlice) Extract

func (s TypesSlice) Extract(typeName string) *TypeInfo

this should be called only from Code's StructByKey method

func (TypesSlice) HasFieldKind added in v0.0.3

func (s TypesSlice) HasFieldKind(kind string) bool

func (TypesSlice) Len added in v0.0.3

func (s TypesSlice) Len() int

implementation of Sorter interface, so we can sort fields

func (TypesSlice) Less added in v0.0.3

func (s TypesSlice) Less(i, j int) bool

func (TypesSlice) Swap added in v0.0.3

func (s TypesSlice) Swap(i, j int)

type VarInfo

type VarInfo struct {
	Name string
	Type *TypeInfo
	Kind string
}

type Vars

type Vars []VarInfo

func (Vars) Len added in v0.0.3

func (s Vars) Len() int

implementation of Sorter interface, so we can sort

func (Vars) Less added in v0.0.3

func (s Vars) Less(i, j int) bool

func (Vars) Swap added in v0.0.3

func (s Vars) Swap(i, j int)

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL