gen

package module
v0.0.0-...-aa80c6e Latest Latest
Warning

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

Go to latest
Published: May 24, 2019 License: GPL-3.0 Imports: 18 Imported by: 0

README

pipeline status coverage report

Coverage Report

Gen is a utility library for inspecting the abtract syntax free of some code and generating code from the tree.

  • CommentInspector - matches particular comments in source files. Useful to generate code from any comment.
  • StructExistsInspector - searches for a particular structure by name in the code. Useful when there is a need to add code to an existing structure.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func StringSliceDiff

func StringSliceDiff(slice1 []string, slice2 []string) []string

StringSliceDiff performs a set difference on two slices of strings.

func StructMapDiff

func StructMapDiff(m1 map[string]*StructInfo, structNames []string) map[string]*StructInfo

StructMapDiff performs a set diff on a map of structName to StructInfo. Returns a map that removes mappings in m2 from m1.

Types

type AstAnalyser

type AstAnalyser interface {
	// GenerateInspector generates an ast.Inspector that gathers specific information about the abstract syntax tree
	// GenerateInspector is called within a go-routine and therefore any state changes will need to protected with locks.
	GenerateInspector(filePath string, astFile *ast.File) Inspector

	// Analyse uses the information gathered from the abstract syntax tree in the GenerateInspector.
	// It is called after the abstract syntax tree of a file
	// is processed with the file name. When Analyse is called nothing may have been found and so it is up to the
	// implementation to keep state across multiple Analyse calls. Analyse is also called within a go-routine so
	// any state changes must be protected with locks.
	Analyse()
}

AstAnalyser is an interface whose implementations are expected to examine an abstract syntax tree for various purposes. AstAnalyers are used in multiple go-routines. GenerateInspector is called within a go-routine and therefore, any implementations of AstAnalyse will need to ensure thread-safety.

type Comment

type Comment struct {
	// Text if the text content of the comment
	Text string

	// Package is which package of the comment
	Package string

	// Pos is the position of the comment in the source file.
	Pos token.Pos

	// Filepath is the file system location of the source file where the comment is found.
	FilePath string
}

Comment represents a comment in a source file.

func (*Comment) Equal

func (comment *Comment) Equal(otherComment *Comment) bool

Equal compares two comment object, return true if they are equal, false otherwise.

func (*Comment) Less

func (comment *Comment) Less(otherComment *Comment) bool

Less return true if comment is less than otherCommand

type CommentAtomicSlice

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

CommentAtomicSlice is an AtomicSlice that maintains state needed to access a slice concurrently.

func NewCommentAtomicSlice

func NewCommentAtomicSlice() *CommentAtomicSlice

NewCommentAtomicSlice creates a new AtomicSlice that can be used in multiple go routines without having to handle locking or unlocking around slice operations.

func (*CommentAtomicSlice) Append

func (commentAtomicSlice *CommentAtomicSlice) Append(v ...*Comment)

Append a string to the commentAtomicSlice. This operation is thread-safe.

func (*CommentAtomicSlice) AppendAtomicSlice

func (commentAtomicSlice *CommentAtomicSlice) AppendAtomicSlice(v ...*CommentAtomicSlice)

AppendAtomicSlice appends another AtomicSlice to another AtomicSlice

func (*CommentAtomicSlice) Contains

func (commentAtomicSlice *CommentAtomicSlice) Contains(item *Comment) bool

Contains returns true if the item exists in the AtomicSlice. Uses the Equal method on the item for determining equality.

func (*CommentAtomicSlice) Delete

func (commentAtomicSlice *CommentAtomicSlice) Delete(index int) (item *Comment)

Delete removed an element of the commentAtomicSlice and returns it. This operation is thread-safe.

func (*CommentAtomicSlice) DeleteEnd

func (commentAtomicSlice *CommentAtomicSlice) DeleteEnd() (item *Comment)

DeleteEnd removes the last element of the commentAtomicSlice and returns it. This operation is thread-safe.

func (*CommentAtomicSlice) Empty

func (commentAtomicSlice *CommentAtomicSlice) Empty() bool

Empty returns true if the length of the string is greater than zero. This operation is thread-safe.

func (*CommentAtomicSlice) Filter

func (commentAtomicSlice *CommentAtomicSlice) Filter(f func(item *Comment) (bool, error)) (*CommentAtomicSlice, error)

Filter every item in the slice to f and returns a new AtomicSlice containing a new set of items. When f returns true the item passed to f is included the new AtomicSlice, otherwise the item is excluded. F is called within a goroutine.

func (*CommentAtomicSlice) FilterMutative

func (commentAtomicSlice *CommentAtomicSlice) FilterMutative(f func(item *Comment) (bool, error)) (*CommentAtomicSlice, error)

FilterMutative calls the function f on every item in the slice. If f returns true, remains in the AtomicSlice, otherwise the item is removed. F is called within a goroutine.

func (*CommentAtomicSlice) Find

func (commentAtomicSlice *CommentAtomicSlice) Find(f func(item *Comment) bool) *Comment

Find passes every item in order to f, which when returns true, ceases looking for an item and returns the item that was most recently passed to f.

func (*CommentAtomicSlice) Foldl

func (commentAtomicSlice *CommentAtomicSlice) Foldl(initial *Comment, f func(initial *Comment, item *Comment) (*Comment, error)) (*Comment, error)

Foldl performs the fold left operation on the slice. Foldl acts like an accumulator, which calls a function f on each item in the slice, using the initial value as the first argument to f with all subsequent calls the results of the previous call of f and the second argument the next value in the slice.

func (*CommentAtomicSlice) Foldr

func (commentAtomicSlice *CommentAtomicSlice) Foldr(initial *Comment, f func(initial *Comment, item *Comment) (*Comment, error)) (*Comment, error)

Foldr performs the fold right operation on the slice. Foldr calls the function f multiple times. F is first called on every item in the slice, with the first argument being the initial value. Once every item in the slice has been passed to f, F is called again on the results of F in the order for which they were most recently computed.

func (*CommentAtomicSlice) Index

func (commentAtomicSlice *CommentAtomicSlice) Index(index int) *Comment

Index returns a string at a particular index. This operation is thread-safe.

func (*CommentAtomicSlice) Length

func (commentAtomicSlice *CommentAtomicSlice) Length() int

Length returns the length of the slice. This operation is thread-safe.

func (*CommentAtomicSlice) Map

func (commentAtomicSlice *CommentAtomicSlice) Map(f func(item *Comment) (*Comment, error)) (*CommentAtomicSlice, error)

Map passes every item in the AtomicStructure to f whose return value is added to a new AtomicStructure. F is called within a goroutine.

func (*CommentAtomicSlice) MapMutative

func (commentAtomicSlice *CommentAtomicSlice) MapMutative(f func(item *Comment) (*Comment, error)) (*CommentAtomicSlice, error)

MapMutative passes every item in the AtomicStructure to f, replacing its value with the return value of f. F is called within a goroutine.

func (*CommentAtomicSlice) Range

func (commentAtomicSlice *CommentAtomicSlice) Range(f func(index int, item *Comment))

Range calls f on each item within a go routine.

func (*CommentAtomicSlice) Search

func (commentAtomicSlice *CommentAtomicSlice) Search(f func(item *Comment) bool) *Comment

Search calls the function f, passing an item as according to the binary search algorithm. Several assumptions are made when using Search:

1. The AtomicSlice has been sorted, if not Search does nothing. 2. The underlying data can be expressed as a range

func (*CommentAtomicSlice) Set

func (commentAtomicSlice *CommentAtomicSlice) Set(index int, v *Comment)

Set string at a particular index This operation is thread-safe.

func (*CommentAtomicSlice) Slice

func (commentAtomicSlice *CommentAtomicSlice) Slice() []*Comment

String returns a copy of a commentAtomicSlice.

func (*CommentAtomicSlice) Sort

func (commentAtomicSlice *CommentAtomicSlice) Sort()

Sort sorts the data using the Less on the underlying data. Later Search can then be used to find. an item. After sorting using any mutative operation on the AtomicSlice invalidates the sort.

func (*CommentAtomicSlice) String

func (commentAtomicSlice *CommentAtomicSlice) String() string

String returns a string representation for the list. Useful for printing out the contents. This operation is thread-safe.

func (*CommentAtomicSlice) WithLock

func (commentAtomicSlice *CommentAtomicSlice) WithLock(f func(*CommentAtomicSliceContextWithLock) error) error

WithLock obtains a write lock on the AtomicSlice and calls the function f, providing it a context that should then only be used to operate on the slice. WithLock allows multiple operations to be performed on the AtomicSlice while ensuring that the slice will not change. Standalone operations on the AtomicSlice all obtain locks and so within f do not directly invoke any methods on the AtomicSlice. Always use the context object, otherwise deadlock will happen.

type CommentAtomicSliceContextWithLock

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

CommentAtomicSliceContextWithLock is used for maintaining a context that is used for invoking multiple mutative operations

func (*CommentAtomicSliceContextWithLock) Append

func (commentAtomicSliceContextWithLock *CommentAtomicSliceContextWithLock) Append(v ...*Comment)

Append adds an item into the AtomicSlice

func (*CommentAtomicSliceContextWithLock) AppendAtomicSlice

func (commentAtomicSliceContextWithLock *CommentAtomicSliceContextWithLock) AppendAtomicSlice(v ...*CommentAtomicSlice)

AppendAtomicSlice appends another AtomicSlice to another AtomicSlice

func (*CommentAtomicSliceContextWithLock) Contains

func (commentAtomicSliceContextWithLock *CommentAtomicSliceContextWithLock) Contains(item *Comment) bool

Contains returns true if the passed item is contained with the AtomicSlice. Uses the Equal method on the underlying data type.

func (*CommentAtomicSliceContextWithLock) Delete

func (commentAtomicSliceContextWithLock *CommentAtomicSliceContextWithLock) Delete(index int) (item *Comment)

Delete removes the item at the particular index, returning it.

func (*CommentAtomicSliceContextWithLock) DeleteEnd

func (commentAtomicSliceContextWithLock *CommentAtomicSliceContextWithLock) DeleteEnd() (item *Comment)

DeleteEnd removes the last item of the AtomicStruct, returning it.

func (*CommentAtomicSliceContextWithLock) Empty

func (commentAtomicSliceContextWithLock *CommentAtomicSliceContextWithLock) Empty() bool

Empty returns true if the AtomicSlice has items, false otherwise.

func (*CommentAtomicSliceContextWithLock) Filter

func (commentAtomicSliceContextWithLock *CommentAtomicSliceContextWithLock) Filter(f func(item *Comment) (bool, error)) (*CommentAtomicSlice, error)

Filter every item in the slice to f and returns a new AtomicSlice containing a new set of items. When f returns true the item passed to f is included the new AtomicSlice, otherwise the item is excluded.

func (*CommentAtomicSliceContextWithLock) FilterMutative

func (commentAtomicSliceContextWithLock *CommentAtomicSliceContextWithLock) FilterMutative(f func(item *Comment) (bool, error)) (*CommentAtomicSlice, error)

FilterMutative calls the function f on every item in the slice. If f returns true, remains in the AtomicSlice, otherwise the item is removed.

func (*CommentAtomicSliceContextWithLock) Foldl

func (commentAtomicSliceContextWithLock *CommentAtomicSliceContextWithLock) Foldl(initial *Comment, f func(initial *Comment, item *Comment) (*Comment, error)) (*Comment, error)

Foldl performs the fold left operation on the slice. Foldl acts like an accumulator, which calls a function f on each item in the slice, using the initial value as the first argument to f with all subsequent calls the results of the previous call of f and the second argument the next value in the slice.

func (*CommentAtomicSliceContextWithLock) Foldr

func (commentAtomicSliceContextWithLock *CommentAtomicSliceContextWithLock) Foldr(initial *Comment, f func(initial *Comment, item *Comment) (*Comment, error)) (*Comment, error)

Foldr performs the fold right operation on the slice. Foldr calls the function f multiple times. F is first called on every item in the slice, with the first argument being the initial value. Once every item in the slice has been passed to f, F is called again on the results of F in the order for which they were most recently computed.

func (*CommentAtomicSliceContextWithLock) Index

func (commentAtomicSliceContextWithLock *CommentAtomicSliceContextWithLock) Index(index int) *Comment

Index returns an item at a particular index.

func (*CommentAtomicSliceContextWithLock) Length

func (commentAtomicSliceContextWithLock *CommentAtomicSliceContextWithLock) Length() int

Length returns the number of items in the AtomicSlice.

func (*CommentAtomicSliceContextWithLock) Map

func (commentAtomicSliceContextWithLock *CommentAtomicSliceContextWithLock) Map(f func(item *Comment) (*Comment, error)) (*CommentAtomicSlice, error)

Map passes every item in the AtomicStructure to f whose return value is added to a new AtomicStructure.

func (*CommentAtomicSliceContextWithLock) MapMutative

func (commentAtomicSliceContextWithLock *CommentAtomicSliceContextWithLock) MapMutative(f func(item *Comment) (*Comment, error)) (*CommentAtomicSlice, error)

MapMutative passes every item in the AtomicStructure to f, replacing its value with the return value of f.

func (*CommentAtomicSliceContextWithLock) Set

func (commentAtomicSliceContextWithLock *CommentAtomicSliceContextWithLock) Set(index int, v *Comment)

Set assigns a item to a particular index. Will panic if setting an index out of bounds.

func (*CommentAtomicSliceContextWithLock) Slice

func (commentAtomicSliceContextWithLock *CommentAtomicSliceContextWithLock) Slice() []*Comment

String returns a new slice containing all the items of the AtomicSlice.

func (*CommentAtomicSliceContextWithLock) Sort

func (commentAtomicSliceContextWithLock *CommentAtomicSliceContextWithLock) Sort()

Sort sorts the AtomicSlice as determined by the Less method defined on the underlying datatype.

func (*CommentAtomicSliceContextWithLock) String

func (commentAtomicSliceContextWithLock *CommentAtomicSliceContextWithLock) String() string

String returns a string representation of the AtomicSlice.

type CommentInspector

type CommentInspector struct {
	MatcherFunc CommentInspectorMatcherFunc
	AnalyseFunc CommentInspectorAnalyseFunc
	// contains filtered or unexported fields
}

CommentInspector is the data structure use to contain the state used to match against comments in the abstract syntax tree.

func NewCommentInspector

func NewCommentInspector(matcher CommentInspectorMatcherFunc, analyse CommentInspectorAnalyseFunc) *CommentInspector

NewCommentInspector creates an inspector that passes all comments found to the passed matcher function. After matching, the analyse function is then called within a go-routine whenever a new matching comment is found.

func (*CommentInspector) Analyse

func (commentInspector *CommentInspector) Analyse()

Analyse is called periodically where any comments that have not yet passed to AnalyseFunc are passed in a slice.

func (*CommentInspector) GenerateInspector

func (commentInspector *CommentInspector) GenerateInspector(filePath string, astFile *ast.File) Inspector

GenerateInspector unlike other AstAnalysers, returns a function that immediately stops the AST traversal and instead immediately compiles a list of matched comments from astFile according to CommentInspectorMatcherFunc.

type CommentInspectorAnalyseFunc

type CommentInspectorAnalyseFunc func(newComments []*Comment)

CommentInspectorAnalyseFunc received a slice of Comments and acts on those comments found.

type CommentInspectorMatcherFunc

type CommentInspectorMatcherFunc func(comment *ast.CommentGroup) bool

CommentInspectorMatcherFunc is a function that receives an ast.CommentGroup to determine which comments in the abstract syntax tree match. Return true if the comment matches, false otherwise.

type Generator

type Generator struct {
	// Analysers is a slice that is used to examine the abstract syntax tree.
	Analysers []AstAnalyser
	// contains filtered or unexported fields
}

Generator consists of one more more Analyzers, which examined an abstract syntax tree for single piece of information.

func NewGenerator

func NewGenerator(options *GeneratorOptions) *Generator

NewGenerator creates a Generator.

func (*Generator) AddAstAnalyzer

func (generator *Generator) AddAstAnalyzer(inspector AstAnalyser)

AddAstAnalyzer adds an AstAnalyzer to the list of Analysers.

func (*Generator) Generate

func (generator *Generator) Generate(name string) (err error)

Generate passes a single file to every AstAnalyzer and then calls AstAnalyzer.Analyse

func (*Generator) GenerateDirectory

func (generator *Generator) GenerateDirectory(rootPath string, directory string) error

GenerateDirectory passes all files within a directory to each AstAnalyzer.

func (*Generator) GenerateDirectoryTree

func (generator *Generator) GenerateDirectoryTree(rootPath string) error

GenerateDirectoryTree traverses a directory tree passing each file to each AstAnalyzer concurrently.

type GeneratorOptions

type GeneratorOptions struct {
	// EnableProgressBar determines whether a progress bar is emitted while generating code.
	EnableProgressBar bool
}

GeneratorOptions are general options that influence how code is generated.

type Inspector

type Inspector func(node ast.Node) bool

Inspector is the function that is passed to ast.Inspect

type StructExistsAnalyseFuncType

type StructExistsAnalyseFuncType func(newStructs map[string]*StructInfo) (err error)

StructExistsAnalyseFuncType defines a function that is called within a go routine when a matching structure is found.

type StructExistsInspector

type StructExistsInspector struct {
	Struct     *map[string]*StructInfo
	StructLock *sync.RWMutex

	AnalyseFunc StructExistsAnalyseFuncType
	// contains filtered or unexported fields
}

StructExistsInspector is an AstAnalyzer that examines an abstract syntax tree for the existence of a structure by a given name.

func NewStructExistsInspector

func NewStructExistsInspector(f StructExistsAnalyseFuncType, structNameList ...string) *StructExistsInspector

NewStructExistsInspector creates an AstAnalyzer that examines an abstract syntax tree for the existence of a structure by a given name. The passed function will be called within a go routine when one of the structures as found.

func (*StructExistsInspector) Analyse

func (findStructInspector *StructExistsInspector) Analyse()

Analyse examines the results from the inspector and determines what has changed since the last time Analyse was called. Any new structs are passed to the StructExistsInspector.AnalyseFunc.

func (*StructExistsInspector) GenerateInspector

func (findStructInspector *StructExistsInspector) GenerateInspector(filePath string, astFile *ast.File) Inspector

GenerateInspector returns a function that when passed to ast.Inspect will populate the corresponding values in the map if the structure is found while traversing the abstract syntax tree.

type StructInfo

type StructInfo struct {
	// Name is the name of the struct
	Name string

	// FilePath is the file system path to the source file where the struct can be found
	FilePath string

	// PackageName is the name of the package where the structure can be found
	PackageName string
}

StructInfo models a struct in the abstract syntax tree.

type TestInspector

type TestInspector struct {
}

TestInspector is an empty struct used for testing purposes.

func NewTestInspector

func NewTestInspector() *TestInspector

NewTestInspector creates an inspector that prints out the abstract syntax tree to better understand the abstract syntax tree when creating other inspectors.

func (*TestInspector) Analyse

func (testInspector *TestInspector) Analyse()

Analyse does nothing for TestInspector because it is not meant to generate code.

func (*TestInspector) GenerateInspector

func (testInspector *TestInspector) GenerateInspector(filePath string, astFile *ast.File) Inspector

GenerateInspector returns a function that prints out nodes of the abstract syntax tree as they are visited. Useful in trying to understand the abstract syntax tree of some code.

Jump to

Keyboard shortcuts

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