codetemplate

package
v0.0.10 Latest Latest
Warning

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

Go to latest
Published: Jun 12, 2022 License: Apache-2.0, BSD-3-Clause Imports: 7 Imported by: 0

Documentation

Overview

Package codetemplate uses a fork of "text/template" to print Go code more concisely.

Users of this package can write "text/template"-style templates for Go code, and any *codegenutil.Symbol that appears as a template variable will be formatting using the GoCode() function using the *codegenutil.FileImports of the file being generated. Furthermore, {{header}} and {{imports}} may be placed in the template text to output "package foo \n imports(...)" or "imports(...)" respectively.

this is an exaple

The "text/template" package has some limitations that make it cumbersome to use for printing Go code. Namely, "fmt.Fprint" is used to print values to the output stream. The fmt package makes it impossible to pass extra contextual information to the object being printed. Because of this limitation, the codetemplate package uses a fork of the "text/template" package that allows using something other than fmt.Fprint to format objects.

Example
template, err := codetemplate.Parse(`// Package mypkg does neat things.
{{header}}

var result1 = {{.maxFn1}}(1, 2)
var result2 = {{.maxFn2}}(1, 2)

func main() {
	fmt.Printf("%f and %f\n", result1, result2)
	fmt.Printf("The people's choice: %f\n", {{.peoplesChoice}})
}
	`)
if err != nil {
	fmt.Printf("error parsing template: %v", err)
	return
}

filePackage := codegenutil.AssumedPackageName("abc.xyz/mypkg")

code := &strings.Builder{}

if err := template.Execute(codegenutil.NewFileImports(filePackage), code, map[string]*codegenutil.Symbol{
	"maxFn1":        codegenutil.Sym("math", "Max"),
	"maxFn2":        codegenutil.Sym("alternative/math", "Max"),
	"peoplesChoice": filePackage.Symbol("result2"),
}); err != nil {
	fmt.Printf("error executing template: %v", err)
	return
}

fmt.Print(code.String())
Output:

// Package mypkg does neat things.
package mypkg

import (
	"math"

	math2 "alternative/math"
)

var result1 = math.Max(1, 2)
var result2 = math2.Max(1, 2)

func main() {
	fmt.Printf("%f and %f\n", result1, result2)
	fmt.Printf("The people's choice: %f\n", result2)
}
Example (UnusedImportPruning)
template, err := codetemplate.Parse(`// Package mypkg does neat things.
{{header}}

import (
	// Log isn't used in the output, so the import declaration is deleted.
	"log"
)

var result1 = {{.maxFn1}}(1, 2)
var result2 = {{.maxFn2}}(1, 2)

func main() {
	fmt.Printf("%f and %f\n", result1, result2)
	fmt.Printf("The people's choice: %f\n", {{.peoplesChoice}})
	{{if .neverTrueCondition}}
		log.Printf("this doesn't appear in the output, and the import is pruned")
	{{end}}
}
	`)
if err != nil {
	fmt.Printf("error parsing template: %v", err)
	return
}

filePackage := codegenutil.AssumedPackageName("abc.xyz/mypkg")

code := &strings.Builder{}

if err := template.Execute(codegenutil.NewFileImports(filePackage), code, map[string]*codegenutil.Symbol{
	"maxFn1":        codegenutil.Sym("math", "Max"),
	"maxFn2":        codegenutil.Sym("alternative/math", "Max"),
	"peoplesChoice": filePackage.Symbol("result2"),
}); err != nil {
	fmt.Printf("error executing template: %v", err)
	return
}

fmt.Print(code.String())
Output:

// Package mypkg does neat things.
package mypkg

import (
	"math"

	math2 "alternative/math"
)

// Log isn't used in the output, so the import declaration is deleted.

var result1 = math.Max(1, 2)
var result2 = math2.Max(1, 2)

func main() {
	fmt.Printf("%f and %f\n", result1, result2)
	fmt.Printf("The people's choice: %f\n", result2)

}

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Option added in v0.0.7

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

Option parameterizes Template construction.

func KeepUnusedImports added in v0.0.7

func KeepUnusedImports() Option

func WithFuncs added in v0.0.8

func WithFuncs(funcs template.FuncMap) Option

WithFuncs specifies the name of the text template creates.

func WithName added in v0.0.8

func WithName(templateName string) Option

WithName specifies the name of the text template creates.

type Template

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

Template is a Go code generation template. See Parse() for details.

func Parse

func Parse(tmplText string, opts ...Option) (*Template, error)

Parse returns a new template by passing tmplText to the parser in "text/template".

The template is evaluated with additional "pipeline" functions:

imports
         A function that takes no arguments and outputs an imports
         block, a.k.a. ImportDecl in the Go spec:
         https://go.dev/ref/spec#ImportDecl.
header
         A function that takes no arguments and outputs a package statement
         and imports block, a.ka. PackageClause and ImportDecl in the Go spec:
         https://go.dev/ref/spec#SourceFile.

func (*Template) Execute

func (t *Template) Execute(imports *codegenutil.FileImports, wr io.Writer, data any) error

Jump to

Keyboard shortcuts

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