codegen

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 21, 2021 License: MIT Imports: 8 Imported by: 4

README

codegen PkgGoDev

codegen is a library for code generators with analysis package.

package mockgen

import (
	"bytes"
	"errors"
	"fmt"
	"go/format"
	"os"

	"github.com/gostaticanalysis/codegen"
	"github.com/gostaticanalysis/knife"
)

var (
	flagTypeName string
	flagOutput   string
)

func init() {
	Generator.Flags.StringVar(&flagTypeName, "type", "", "type name of interface")
	Generator.Flags.StringVar(&flagOutput, "o", "", "output file name")
}

var Generator = &codegen.Generator{
	Name: "mockgen",
	Doc:  "mockgen generates a mock of interface",
	Run: func(pass *codegen.Pass) error {
		if flagTypeName == "" {
			return errors.New("type must be specified")
		}

		td := &knife.TempalteData{
			Fset:      pass.Fset,
			Files:     pass.Files,
			TypesInfo: pass.TypesInfo,
			Pkg:       pass.Pkg,
			Extra: map[string]interface{}{
				"type": flagTypeName,
			},
		}
		t, err := knife.NewTemplate(td).Parse(tmpl)
		if err != nil {
			return err
		}

		var buf bytes.Buffer
		if err := t.Execute(&buf, knife.NewPackage(pass.Pkg)); err != nil {
			return err
		}

		src, err := format.Source(buf.Bytes())
		if err != nil {
			return err
		}

		if flagOutput == "" {
			pass.Print(string(src))
			return nil
		}

		f, err := os.Create(flagOutput)
		if err != nil {
			return err
		}

		fmt.Fprint(f, string(src))

		if err := f.Close(); err != nil {
			return err
		}

		return nil
	},
}

var tmpl = `{{with index .Types (data "type")}}{{if interface .}}
// Code generated by mockgen; DO NOT EDIT.
package {{(pkg).Name}}
type Mock{{data "type"}} struct {
{{- range $n, $f := methods .}}
	{{$n}}Func {{$f.Signature}}
{{- end}}
}
{{range $n, $f := methods .}}
func (m *Mock{{data "type"}}) {{$n}}({{range $f.Signature.Params}}
	{{- .Name}} {{.Type}},
{{- end}}) ({{range $f.Signature.Results}}
	{{- .Name}} {{.Type}},
{{- end}}) {
	{{if $f.Signature.Results}}return {{end}}m.{{$n}}Func({{range $f.Signature.Params}}
		{{- .Name}},
	{{- end}})
}
{{end}}
{{end}}
{{end}}
`

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Generator

type Generator struct {
	// The Name of the generator must be a valid Go identifier
	// as it may appear in command-line flags, URLs, and so on.
	Name string

	// Doc is the documentation for the generator.
	// The part before the first "\n\n" is the title
	// (no capital or period, max ~60 letters).
	Doc string

	// Flags defines any flags accepted by the generator.
	// The manner in which these flags are exposed to the user
	// depends on the driver which runs the generator.
	Flags flag.FlagSet

	// Run applies the generator to a package.
	// It returns an error if the generator failed.
	//
	// To pass analysis results of depended analyzers between packages (and thus
	// potentially between address spaces), use Facts, which are
	// serializable.
	Run func(*Pass) error

	// RunDespiteErrors allows the driver to invoke
	// the Run method of this generator even on a
	// package that contains parse or type errors.
	RunDespiteErrors bool

	// Requires is a set of analyzers that must run successfully
	// before this one on a given package. This analyzer may inspect
	// the outputs produced by each analyzer in Requires.
	// The graph over analyzers implied by Requires edges must be acyclic.
	//
	// Requires establishes a "horizontal" dependency between
	// analysis passes (different analyzers, same package).
	Requires []*analysis.Analyzer

	Output func(pkg *types.Package) io.Writer
}

A Generator describes a code generator function and its options.

func (*Generator) ToAnalyzer

func (g *Generator) ToAnalyzer() *analysis.Analyzer

ToAnalyzer converts the generator to an analyzer.

type Pass

type Pass struct {
	Generator *Generator // the identity of the current generator

	// syntax and type information
	Fset       *token.FileSet // file position information
	Files      []*ast.File    // the abstract syntax tree of each file
	OtherFiles []string       // names of non-Go files of this package
	Pkg        *types.Package // type information about the package
	TypesInfo  *types.Info    // type information about the syntax trees
	TypesSizes types.Sizes    // function for computing sizes of types

	// ResultOf provides the inputs to this analysis pass, which are
	// the corresponding results of its prerequisite analyzers.
	// The map keys are the elements of Analysis.Required,
	// and the type of each corresponding value is the required
	// analysis's ResultType.
	ResultOf map[*analysis.Analyzer]interface{}

	// Output is the destination of the generator.
	// Pass's Print, Println, Printf outputs to this writer.
	Output io.Writer

	// ImportObjectFact retrieves a fact associated with obj.
	// Given a value ptr of type *T, where *T satisfies Fact,
	// ImportObjectFact copies the value to *ptr.
	//
	// ImportObjectFact panics if called after the pass is complete.
	// ImportObjectFact is not concurrency-safe.
	ImportObjectFact func(obj types.Object, fact analysis.Fact) bool

	// ImportPackageFact retrieves a fact associated with package pkg,
	// which must be this package or one of its dependencies.
	// See comments for ImportObjectFact.
	ImportPackageFact func(pkg *types.Package, fact analysis.Fact) bool
}

A Pass provides information to the Run function that applies a specific generator to a single Go package. The Run function should not call any of the Pass functions concurrently.

func (*Pass) Print

func (pass *Pass) Print(a ...interface{}) (n int, err error)

Print is a wrapper of fmt.Fprint with pass.Output.

func (*Pass) Printf

func (pass *Pass) Printf(format string, a ...interface{}) (n int, err error)

Printf is a wrapper of fmt.Fprintf with pass.Output.

func (*Pass) Println

func (pass *Pass) Println(a ...interface{}) (n int, err error)

Println is a wrapper of fmt.Fprintln with pass.Output.

Directories

Path Synopsis
_example
Package codegentest provides utilities for testing generators.
Package codegentest provides utilities for testing generators.
Package singlegenerator defines the main function for only a single code generator.
Package singlegenerator defines the main function for only a single code generator.

Jump to

Keyboard shortcuts

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