gtigen

package
v0.1.32 Latest Latest
Warning

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

Go to latest
Published: Dec 26, 2023 License: BSD-3-Clause Imports: 16 Imported by: 2

Documentation

Overview

Package gtigen provides the generation of general purpose type information for Go types, methods, functions and variables

Index

Constants

This section is empty.

Variables

View Source
var AllowedEnumTypes = map[string]bool{"int": true, "int64": true, "int32": true, "int16": true, "int8": true, "uint": true, "uint64": true, "uint32": true, "uint16": true, "uint8": true}

AllowedEnumTypes are the types that can be used for enums that are not bit flags (bit flags can only be int64s). It is stored as a map for quick and convenient access.

View Source
var FuncTmpl = template.Must(template.New("Func").Parse(
	`
	var _ = gti.AddFunc(&gti.Func{
		Name: "{{.Name}}",
		Doc: {{printf "%q" .Doc}},
		Directives: {{printf "%#v" .Directives}},
		Args: {{printf "%#v" .Args}},
		Returns: {{printf "%#v" .Returns}},
	})
	`))

FuncTmpl is the template for gti.Func declarations. It takes a *gti.Func as its value.

View Source
var SetterMethodsTmpl = template.Must(template.New("SetterMethods").
	Funcs(template.FuncMap{
		"SetterFields": SetterFields,
		"SetterName":   SetterName,
		"DocToComment": DocToComment,
	}).Parse(
	`
	{{$typ := .}}
	{{range (SetterFields .)}}
	// Set{{SetterName .}} sets the [{{$typ.Name}}.{{.Name}}] {{- if ne .Doc ""}}:{{end}}
	{{DocToComment .Doc}}
	func (t *{{$typ.Name}}) Set{{SetterName .}}(v {{.LocalType}}) *{{$typ.Name}} {
		t.{{.Name}} = v
		return t
	}
	{{end}}
`))

SetterMethodsTmpl is the template for setter methods for a type. It takes a *Type as its value.

View Source
var TypeTmpl = template.Must(template.New("Type").Parse(
	`
	{{if .Config.TypeVar}} // {{.Name}}Type is the [gti.Type] for [{{.Name}}]
	var {{.Name}}Type {{else}} var _ {{end}} = gti.AddType(&gti.Type{
		Name: "{{.FullName}}",
		ShortName: "{{.ShortName}}",
		IDName: "{{.IDName}}",
		Doc: {{printf "%q" .Doc}},
		Directives: {{printf "%#v" .Directives}},
		{{if ne .Fields nil}} Fields: {{printf "%#v" .Fields}}, {{end}}
		{{if ne .Embeds nil}} Embeds: {{printf "%#v" .Embeds}}, {{end}}
		Methods: {{printf "%#v" .Methods}},
		{{if .Config.Instance}} Instance: &{{.Name}}{}, {{end}}
	})
	`))

TypeTmpl is the template for gti.Type declarations. It takes a *Type as its value.

Functions

func DocToComment added in v0.1.11

func DocToComment(doc string) string

DocToComment converts the given doc string to an appropriate comment string.

func FullName

func FullName(pkg *packages.Package, name string) string

FullName returns the fully qualified name of an identifier in the given package with the given name.

func Generate

func Generate(cfg *Config) error

Generate generates gti type info, using the configuration information, loading the packages from the configuration source directory, and writing the result to the configuration output file.

It is a simple entry point to gtigen that does all of the steps; for more specific functionality, create a new Generator with NewGenerator and call methods on it.

func GeneratePkgs

func GeneratePkgs(cfg *Config, pkgs []*packages.Package) error

GeneratePkgs generates enum methods using the given configuration object and packages parsed from the configuration source directory, and writes the result to the config output file. It is a simple entry point to gtigen that does all of the steps; for more specific functionality, create a new Generator with NewGenerator and call methods on it.

func LoadFromComment

func LoadFromComment(c *ast.CommentGroup, cfg *Config) (dirs gti.Directives, hasAdd bool, hasSkip bool, err error)

LoadFromComment processes the given comment group, setting the values of the given config object based on any gti directives in the comment group, and returning all directives found, whether there was a gti:add directive, and any error. If the given documentation is nil, LoadFromComment still returns an empty but valid gti.Directives value, false, and no error.

func LoadFromComments added in v0.1.11

func LoadFromComments(cfg *Config, c ...*ast.CommentGroup) (dirs gti.Directives, hasAdd bool, hasSkip bool, err error)

LoadFromComments is a helper function that combines the results of LoadFromComment for the given comment groups.

func LocalTypeNameQualifier added in v0.1.11

func LocalTypeNameQualifier(pkg *types.Package) types.Qualifier

LocalTypeNameQualifier returns a types.Qualifier similar to that returned by types.RelativeTo, but using the package name instead of the package path so that it can be used in code.

func PackageModes

func PackageModes(cfg *Config) packages.LoadMode

PackageModes returns the package load modes needed for gtigen, based on the given config information.

func ParsePackages added in v0.1.1

func ParsePackages(cfg *Config) ([]*packages.Package, error)

ParsePackages parses the package(s) located in the configuration source directory.

func SetterFields added in v0.1.11

func SetterFields(typ *Type) []*gti.Field

SetterFields returns all of the fields and embedded fields of the given type that don't have a `set:"-"` struct tag.

func SetterName added in v0.1.11

func SetterName(field *gti.Field) string

SetterName returns the name that should be used for the setter function for the given field. It first checks the 'set' struct tag and falls back on the name of the field.

Types

type Config

type Config struct {

	// the source directory to run gtigen on (can be set to multiple through paths like ./...)
	Dir string `def:"." posarg:"0" required:"-"`

	// the output file location relative to the package on which gtigen is being called
	Output string `def:"gtigen.go"`

	// whether to add types to gtigen by default
	AddTypes bool

	// whether to add methods to gtigen by default
	AddMethods bool

	// whether to add functions to gtigen by default
	AddFuncs bool

	// An ordered map of configs keyed by fully-qualified interface type names; if a type implements the interface, the config will be applied to it.
	// The configs are applied in sequential ascending order, which means that
	// the last config overrides the other ones, so the most specific
	// interfaces should typically be put last.
	// Note: the package gtigen is run on must explicitly reference this interface at some point for this to work; adding a simple
	// `var _ MyInterface = (*MyType)(nil)` statement to check for interface implementation is an easy way to accomplish that.
	// Note: gtigen will still succeed if it can not find one of the interfaces specified here in order to allow it to work generically across multiple directories; you can use the -v flag to get log warnings about this if you suspect that it is not finding interfaces when it should.
	InterfaceConfigs *ordmap.Map[string, *Config]

	// whether to generate an instance of the type(s)
	Instance bool

	// whether to generate a global type variable of the form 'TypeNameType'
	TypeVar bool

	// Whether to generate chaining `Set*` methods for each field of each type (eg: "SetText" for field "Text").
	// If this is set to true, then you can add `set:"-"` struct tags to individual fields
	// to prevent Set methods being generated for them.
	Setters bool

	// a slice of templates to execute on each type being added; the template data is of the type gtigen.Type
	Templates []*template.Template
}

Config contains the configuration information used by gtigen

type Generator

type Generator struct {
	Config     *Config                               // The configuration information
	Buf        bytes.Buffer                          // The accumulated output.
	Pkgs       []*packages.Package                   // The packages we are scanning.
	Pkg        *packages.Package                     // The packages we are currently on.
	File       *ast.File                             // The file we are currently on.
	Cmap       ast.CommentMap                        // The comment map for the file we are currently on.
	Types      []*Type                               // The types
	Methods    *ordmap.Map[string, []*gti.Method]    // The methods, keyed by the the full package name of the type of the receiver
	Funcs      *ordmap.Map[string, *gti.Func]        // The functions
	Interfaces *ordmap.Map[string, *types.Interface] // The cached interfaces, created from [Config.InterfaceConfigs]
}

Generator holds the state of the generator. It is primarily used to buffer the output.

func NewGenerator

func NewGenerator(config *Config, pkgs []*packages.Package) *Generator

NewGenerator returns a new generator with the given configuration information and parsed packages.

func (*Generator) ExecTmpl

func (g *Generator) ExecTmpl(t *template.Template, data any)

ExecTmpl executes the given template with the given data and writes the result to [Generator.Buf]. It fatally logs any error. All gtigen templates take a *Type or *gti.Func as their data.

func (*Generator) Find

func (g *Generator) Find() error

Find goes through all of the types, functions, variables, and constants in the package, finds those marked with gti:add, and adds them to [Generator.Types] and [Generator.Funcs]

func (*Generator) Generate

func (g *Generator) Generate() (bool, error)

Generate produces the code for the types stored in [Generator.Types] and stores them in [Generator.Buf]. It returns whether there were any types to generate methods for, and any error that occurred.

func (*Generator) GetEmbeddedFields added in v0.1.11

func (g *Generator) GetEmbeddedFields(efields *gti.Fields, typ, startTyp types.Type)

GetEmbeddedFields recursively adds to the given set of embedded fields all of the embedded fields for the given type. It does not add the fields in the given starting type, as those fields aren't embedded.

func (*Generator) GetFields added in v0.1.7

func (g *Generator) GetFields(list *ast.FieldList, cfg *Config) (*gti.Fields, error)

GetFields creates and returns a new gti.Fields object from the given ast.FieldList, in the context of the given surrounding config. If the given field list is nil, GetFields still returns an empty but valid gti.Fields value and no error.

func (*Generator) GetInterfaces

func (g *Generator) GetInterfaces() error

GetInterfaces sets [Generator.Interfaces] based on [Generator.Config.InterfaceConfigs]. It should typically not be called by end-user code.

func (*Generator) Inspect

func (g *Generator) Inspect(n ast.Node) (bool, error)

Inspect looks at the given AST node and adds it to [Generator.Types] if it is marked with an appropriate comment directive. It returns whether the AST inspector should continue, and an error if there is one. It should only be called in ast.Inspect.

func (*Generator) InspectFuncDecl

func (g *Generator) InspectFuncDecl(fd *ast.FuncDecl) (bool, error)

InspectFuncDecl is the implementation of Generator.Inspect for ast.FuncDecl nodes.

func (*Generator) InspectGenDecl

func (g *Generator) InspectGenDecl(gd *ast.GenDecl) (bool, error)

InspectGenDecl is the implementation of Generator.Inspect for ast.GenDecl nodes.

func (*Generator) LoadFromNodeComments added in v0.1.11

func (g *Generator) LoadFromNodeComments(cfg *Config, n ast.Node) (dirs gti.Directives, hasAdd bool, hasSkip bool, err error)

LoadFromNodeComments is a helper function that calls LoadFromComments with the correctly filtered comment map comments of the given node.

func (*Generator) PrintHeader

func (g *Generator) PrintHeader()

PrintHeader prints the header and package clause to the accumulated output

func (*Generator) Printf

func (g *Generator) Printf(format string, args ...any)

Printf prints the formatted string to the accumulated output in [Generator.Buf]

func (*Generator) Write

func (g *Generator) Write() error

Write formats the data in the the Generator's buffer ([Generator.Buf]) and writes it to the file specified by [Generator.Config.Output].

type Type

type Type struct {
	Name           string         // The name of the type in its package (eg: MyType)
	FullName       string         // The fully package-path-qualified name of the type (eg: goki.dev/gi/v2.Button)
	ShortName      string         // The short, package-qualified name of the type (eg: gi.Button)
	IDName         string         // The short, package-unqualified, kebab-case name of the type, suitable for use in an ID (eg: button)
	Type           *ast.TypeSpec  // The standard AST type value
	Doc            string         // The documentation for the type
	Pkg            string         // The name of the package the type is in
	Directives     gti.Directives // The directives for the type; guaranteed to be non-nil
	Fields         *gti.Fields    // The fields of the struct type; nil if not a struct
	Embeds         *gti.Fields    // The embeds of the struct type; nil if not a struct
	EmbeddedFields *gti.Fields    // The fields contained within the embeds of the struct type; nil if not a struct, and used for generating setters only
	Methods        *gti.Methods   // The methods of the type; guaranteed to be non-nil
	Config         *Config        // Configuration information set in the comment directive for the type; is initialized to generator config info first
}

Type represents a parsed type.

Jump to

Keyboard shortcuts

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