gogh

package module
v0.22.0 Latest Latest
Warning

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

Go to latest
Published: May 17, 2024 License: MIT Imports: 30 Imported by: 6

README

gogh

Go source code rendering library. The name gogh comes from both GO Generator and from the fact I adore Van Gogh writings.

Installation

go get github.com/sirkon/gogh

Simple usage

package main

import (
	"github.com/sirkon/errors"
	"github.com/sirkon/gogh"
	"github.com/sirkon/message"
)

func main() {
	prj, err := gogh.New(
		gogh.GoFmt,
		func(r *gogh.Imports) *gogh.Imports {
			return r
		},
	)
	if err != nil {
		message.Fatal(errors.Wrap(err, "setup module info"))
	}

	pkg, err := prj.Root("project")
	if err != nil {
		message.Fatal(errors.Wrap(err, "setup package "+prj.Name()))
	}

	r := pkg.Go("main.go", gogh.Shy)

	r.Imports().Add("fmt").Ref("fmt")

	r.L(`func main() {`)
	r.L(`    $fmt.Println("Hello $0!")`, "World")
	r.L(`}`)

	if err := prj.Render(); err != nil {
		message.Fatal(errors.Wrap(err, "render module"))
	}
}

Importers

It would be great to have shortcuts for frequently imported packages besides generic

r.Imports().Add("<pkg path>")

isn't it?

Luckily, it is possible and pretty easy since Go supports generics now. All you need is to define your custom type satisfying gogh.Importer interface

// Importer an abstraction covert Imports
type Importer interface {
Imports() *Imports
Add(pkgpath string) *ImportAliasControl
Module(relpath string) *ImportAliasControl
}

Something like this will work:

package pkg

import "github.com/sirkon/gogh"

func NewCustomImporter(i *gogh.Imports) *CustomImporter {
	return &CustomImporter{
		i: i,
	}
}

type CustomImporter struct {
	i *gogh.Imports
}

func (i *CustomImporter) Imports() *gogh.Imports {
	return i.i
}

func (i *CustomImporter) Add(pkgpath string) *gogh.ImportAliasControl {
	return i.i.Add(pkgpath)
}

func (i *CustomImporter) Module(pkgpath string) *gogh.ImportAliasControl {
	return i.i.Module(pkgpath)
}

func (i *CustomImporter) Company(relpath string) *gogh.ImportAliasControl {
	return i.i.Add("company.org/gopkgs/" + relpath)
}

And then just

mod, err := gogh.New(gogh.GoFmt, NewCustomImporter)
…

r.Imports().Company("configs").Ref("configs")
r.L(`// Config service $0 config definition`, serviceName)
r.L(`type Config struct{`)
r.L(`    TLS *$configs.TLS`)
r.L(`    Service *$configs.Service`)
r.L(`}`)

How to use text renderer.

Method Description
L(format, params...) Render and put text line using custom format.
See further for details.
C(params...) Render a text concatenation of given parameters.
R(text) Put raw text
N() Put new line
S(format, params...) Same as L but returns rendered text as a string without saving it.
Z() Returns a new renderer which will put lines before
any line made by the original renderer.
Set details below.
T() Returns a new "temporary" renderer which belong to
the same package but will not produce
any new file.
F(…) Renders definition of a function. The primary goal is to simplify building functions
definitions based on existing signatures.
M(…) Similar to F but for methods this time.
Type(t) Renders fully qualified type name of types.Type instance.
Will take care of package qualifier names and imports.
Proto(t) Renders fully qualified type name defined in protoast.
Uniq(name, hints) Returns unique name using value of name as a basis.
See further details below.
Taken(name)) Checks if this name was taken before.
Let(name, value) Sets immutable variable into the rendering context.
Can be addressed in format strings further.
See details below.
TryLet(name, value) Same as let but won't panic if the name was taken before.
Scope() Produce a new renderer with its local context.
Uniq and *Let calls will not touch the original renderer.
See details below.
InnerScope(func) Produce a new scope and feed it to the given function.

Formatting.

The formatting is built upon the go-format library, but there is some extra functionality.

  • types.Type and ast.Type are supported out of the box and converted into strings automatically.
  • (*)Commas and (*)Params are also supported with their custom format option \n, which will render their multiline representation.

And then string (and fmt.Stringer) arguments have these dedicated formatting options:

format option details
P Applies gogh.Public function to the value.
p Applies gogh.Private function.
R Applies gogh.Proto function.
_ Applies gogh.Underscored function.
- Applies gogh.Striked function.

Lazy generation.

Imagine you have a list of [{ name, typeName }] and want to generate:

  1. Structured type having respective fields.
  2. Constructor of this type.
  3. Both in just one pass over that list.

This will work:

r.L(`type Data struct {`)
s := r.Z() // s is for structure generation
r.L(`}`)

r.N()
r.L(`func dataConstructor(`)
a := r.Z() // a for constructor arguements generation
r.L(`) *Data {`)
r.L(`    return &Data{`)
c := r.Z() // c for fields assigns
r.L(`    }`)
r.L(`}`)


for _, item := range typesTypeNamesList {
	s.L(`$0 $1`, item.name, item.typeName)
	a.L(`$0 $1,`, item.name, item.typeName)
	c.L(`$0: $1,`, item.name)
}

Scope.

Every renderer has a scope which can be used to generate unique values and keep rendering context values. Different renderers can share the same scope though: r.Z() call produces a new renderer but its scope is identical to one r has.

r.Scope() called in a moment of time t produces a new renderer with a new scope, which:

  • Has the same set of uniqs registered. So their consecutive Uniq calls with same names and hints will have the same output.
  • Has identical rendering context, so all variables available at the moment of time t for the original renderer will be avaiable for the new one too.
  • Scopes splits after this, meaning new uniqs and context values made for one renderer will not reflect into the another.
  • Yet, imports with Ref made with one of renderers will reflect into all others rendering on the same file. This is a reasonable decision as package imports are global for a given Go file and all renderers produced with Z or Scope belong to the same file.

Unique scope values.

Let we have to ensure unique values. For, to say, function arguments. Uniq method is to help us here. How it works:

  • There's a base name.
  • There'is optional hint suffix. It is defined as a vararg, but only the first one can be taken into account.

It tries:

  1. Just a base name first. Return if it was not taken.
  2. Base name is busy. It tries <baseName><Hint suffix> if there's a hint.
  3. If both base name and even a hinted base name are busy it looks for the first unique <base>N for N = 1, 2, 3, … which have not been taken yet.

Scope rendering context.

Using positional values for formatting can be annoying. You can push some constant values into the so-called scope rendering context. Example:

r.Let("val", someReallyAnnoyingVariableName)
r.L(`$fmt.Println($val)`)

Let panics if you tries to define a new value for the variable you have added already.

Advices.

  • Use Ref to assign rendering context value is the preferable way to access imported packages: *gogh.GoRenderer will take care of conflicting names, aliases, etc. Just make sure reference name is unique for the renderer.
  • Use type aliases if your function calls have renderers in their arguments. Because it is awkward to have something like
    func (g *Generator) renderSomething(r *gogh.GoRenderer[*gogh.Imports]) {…}
    
    Just put
    type goRenderer = gogh.GoRenderer[*gogh.Imports]
    
    somewhere and then you will have
    func (g *Generator) renderSomething(r *goRenderer) {…}
    
  • You can use M or F methods to copy signatures of existing functions in an easy way.

About mimchain utility.

Installation.

go install github.com/sirkon/gogh/cmd/mimchain

What is it?

It is a tool to generate rendering helpers mimicking types with chaining methods. Take a look at my custom errors package. It is done to deliver structured context with errors, for structured loggers mostly in order to follow "log only once" approach:

return 0, errors.Wrap(err, "count something").Int("stopped-count-at", count).Str("place", "placeName")

where we collect context, including structured context into errors and log them just once at the root level.

Building these with just a renderer can be pretty annoying:

r.L(`return $ReturnZeroValues $errors.Wrap(err, "count $0").Int("stopped-count-at, $countVar).Str("place", "some error place")`, what)

This utility can generate dedicated code renderers that can be somewhat easier to use with an IDE support:

ers.R(r, what).Wrap("err", "count $0").Int("stopped-count-at", "$countVar").Str("place", placeName)

The code it produces is not ready to use though:

  • No constructors like R for generated rendering entities. You need to write what's needed.
  • Another issue is with string arguments. See at the code sample above: some methods like Bool, Str, Uint64, etc, will be called with a direct string literal as their first argument mostly and the second argument is very likely to be a variable.

The first part is trivial, you can write it yourself with all tweaks you want. The second is harder. There's an option currently which enables force quotes for constructors and type methods renderers. A code generated will quote an argument if it always has string type for functions having the same amount of parameters.

And remember: it is not a crime to tweak generated code manually, the lack of "DO NOT EDIT" header there is not a coincidence.

This library provides Q, L and QuoteBias helpers to deal with string quotes:

  • Q is useful when string values are meant to have literal rendering – it will turn them into quoted strings.
  • L is a vice versa – it is useful when string values are meant to have quoted rendering.
  • QuoteBias function turns strings values into quoted strings.

These are meant to be used for relatively easy tweaking of a source code generated.

Example.

It is testexample.

Documentation

Index

Constants

View Source
const (

	// ReturnZeroValues is used as a renderer's scope key to represent
	// zero values in a function returning on, most likely, errors processing.
	//
	// It is computed automatically in some cases
	ReturnZeroValues = "ReturnZeroValues"
)

Variables

This section is empty.

Functions

func FancyFmt added in v0.7.0

func FancyFmt(src []byte) ([]byte, error)

FancyFmt formats source code with github.com/sirkon/fancyfmt

func GoFmt added in v0.7.0

func GoFmt(src []byte) ([]byte, error)

GoFmt formats source code with gofmt

func GoRendererBuffer added in v0.18.0

func GoRendererBuffer[T Importer](r *GoRenderer[T]) *bytes.Buffer

GoRendererBuffer switches the given renderer to a new block two times and returns a buffer of the block that was the current after the first switch.

See what is happening here:

  • B is a current block before the call.
  • A is a current block after the first switch.
  • C is a current block after the second switch.

And

Original blocks:  …, B₋, B, B₊, …
First switch:     …, B₋, B, A, B₊, …
Second switch:    …, B₋, B, A, C, B₊, …

We could actually do only one switch and return a black that was the current before the switch, but it can be pretty unsafe, becaue:

  • A user can mutate buffer data by an accident.
  • Contents of blocks is always concatenated with LF between them. The usage of the dedicated block ensures the user is not needed to care about new lines.

This double switch makes it sure we are safe from these sorts of issues.

This function aimed for an external usage. mimchain output uses this BTW.

func Private added in v0.7.0

func Private(head string, parts ...string) string

Private same as public, just Go-private

func Proto added in v0.7.0

func Proto(head string, parts ...string) string

Proto returns Go-public camel cased word matching protoc-gen-go

func Public added in v0.7.0

func Public(head string, parts ...string) string

Public returns a Go-public golint-aware camel cased word built upon head and parts joined with _

func QuoteBias added in v0.21.0

func QuoteBias(v any) any

QuoteBias returns just v if it is not a string. Returns Q(v) otherwise.

func RegisterInitalism added in v0.7.0

func RegisterInitalism(word string)

RegisterInitalism registers initialisms to be used in casings.

func Shy added in v0.7.0

func Shy(r renderingOptionsHandler) bool

Shy prevents overwrite of existing file

func Striked added in v0.7.0

func Striked(head string, parts ...string) string

Striked returns striked case of a word, this is same as Underscored, just with - instead of _

func Underscored added in v0.7.0

func Underscored(head string, parts ...string) string

Underscored returns underscored case of a word

Types

type AliasCorrector added in v0.7.0

type AliasCorrector func(name, pkgpath string) string

AliasCorrector this function may alter alias for a package with the given name and path in case of name conflict. Empty string means no correction for the given pkgpath.

type Commas added in v0.4.0

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

Commas comma-separated list

func A added in v0.17.0

func A(a ...string) Commas

A shortcut function to create comma separated list out of string list values quickly.

func (*Commas) Add added in v0.10.0

func (c *Commas) Add(value string) *Commas

Add adds new value

func (*Commas) Multi added in v0.10.0

func (s *Commas) Multi() string

Multi returns a parameters text representation written in one per line

func (Commas) String added in v0.4.0

func (s Commas) String() string

String returns a line of comma-separated entities

type Formatter added in v0.7.0

type Formatter func([]byte) ([]byte, error)

Formatter is a signature of source code formatting function. GoFmt and FancyFmt are provided by this package.

type GoFuncBodyRenderer added in v0.17.0

type GoFuncBodyRenderer[T Importer] struct {
	// contains filtered or unexported fields
}

GoFuncBodyRenderer renders function/method body.

func (*GoFuncBodyRenderer[T]) Body added in v0.17.0

func (r *GoFuncBodyRenderer[T]) Body(f func(r *GoRenderer[T]))

Body renders function body with the provided f function.

type GoFuncRenderer added in v0.17.0

type GoFuncRenderer[T Importer] struct {
	// contains filtered or unexported fields
}

GoFuncRenderer renders definitions of functions and methods.

func (*GoFuncRenderer[T]) Body added in v0.17.0

func (r *GoFuncRenderer[T]) Body(f func(r *GoRenderer[T]))

Body this renders function/method body.

func (*GoFuncRenderer[T]) Returns added in v0.17.0

func (r *GoFuncRenderer[T]) Returns(results ...any) *GoFuncBodyRenderer[T]

Returns sets up a return tuple of the function.

We don't divide fmt.Stringer or string here, except stringers from types or ast [libraries

Arguments are treated almost the same way as for function/method calls, it can be:

  • missing at all
  • a single instance of Params or *Params
  • a single instance of Commas or *Commas
  • a single instance of *types.Tuple.
  • a list of *types.Var.
  • a list of (K₁, V₁, K₂, V₂, ..., Kₙ, Vₙ), where *types.Var are not allowed for Ks anv Vs, Ks must be string or stringers and Vs must be string or stringers or *types.Tuple or and each Kᵢ value or String() can either be .
  • a list of (T₁, T₂, …, T₂ₙ₋₁) composed entirely of strings or fmt.Stringers with the last value being empty string (or .String() method returning an empty string)

It may produce zero values expression for a return statement, but this rather depends on types, if this call could deduce their values. It puts zero expression into the rendering context under ReturnZeroValues name.

Specifics:

  • If the last argument type is the error, "zero value" of the last return type is empty. It is because we mostly need them (zero values) to return an error, where we will be setting an expression for the last return value (error) ourselves.
  • Zero values depend on return types. We can only rely on text matching heuristics if types are represented as strings. We wouldn't have much trouble with types.Type or ast.Type though. In case if our return values are named, "zeroes" will be just these names. Except the case of "_" names of course, where we will use heuristics again.

Raw text heuristics rules:

  • Builtin types like int, uint32, bool, string, etc are supported, even though they may be shadowed somehow. We just guess they weren't and this is acceptable for most cases.
  • Chans, maps, slices, pointers are supported too.
  • Error type is matched by its name, same guess as for builtins here.

type GoRenderer added in v0.7.0

type GoRenderer[T Importer] struct {
	// contains filtered or unexported fields
}

GoRenderer GoFile source file code generation.

The text data it used for code rendering is kept in a sequence of text blocksmgr, where the renderer instance reference one of them, it is called a current block for the renderer.

Renderer also provides means to control import statements.

Overall, you can:

  • Add new import paths.
  • Append a text to the current block of the renderer.
  • Insert a new text block after the current one and make the current block switched to it. Read Z method docs to learn what it gives.

The generated text consists of two major parts:

  1. Auto generated header with file comment, package statement and import statements.
  2. A concatenated text from an ordered sequence of text blocksmgr.

With the GoRenderer you can:

func (*GoRenderer[T]) C added in v0.20.0

func (r *GoRenderer[T]) C(a ...any)

C concatenates given objects into a single text line using space character as a separator.

func (*GoRenderer[T]) F added in v0.17.0

func (r *GoRenderer[T]) F(name string) func(params ...any) *GoFuncRenderer[T]

F function definition rendering helper. Here name is just a function name and params can be:

  • missing at all
  • a single instance of Params or *Params
  • a single instance of Commas or *Commas
  • a single instance of *types.Tuple, where names MUST NOT be empty.
  • a list of *types.Var, where names in each one MUST NOT be empty.
  • a list of (K₁, V₁, K₂, V₂, ..., Kₙ, Vₙ), where Kᵢ = (string | fmt.Stringer), except *types.Var even though it is fmt.Stringer. Vᵢ = (string | fmt.Stringer | types.Type | ast.Type) except *types.Var. and each Kᵢ value or String() can either be.
  • a list of (T₁, T₂, …, T₂ₙ₋₁) composed entirely of strings or fmt.Stringers with the last value being empty string (or .String() method returning an empty string) and all other values looking like "<name> <type".

Usage example:

r.F("name")(

func (*GoRenderer[T]) Imports added in v0.7.0

func (r *GoRenderer[T]) Imports() T

Imports returns imports controller.

Usage example:

r.Import().Add("errors").Manager("errs")
r.L(`    return $errs.New("error")`)

Will render:

return errors.New("error")

Remember, using Manager to put package name into the scope is highly preferable over no Manager or setting package name manually (via the As call): It will take care of conflicting package names, you won't need to resolve dependencies manually.

Beware though: do not use the same Manager name for different packages and do not try to Manager with the name you have used with Let before.

func (*GoRenderer[T]) InCtx added in v0.16.0

func (r *GoRenderer[T]) InCtx(name string) bool

InCtx checks if this name is already in the rendering context.

func (*GoRenderer[T]) InnerScope added in v0.16.0

func (r *GoRenderer[T]) InnerScope(f func(r *GoRenderer[T]))

InnerScope creates a new scope and feeds it into the given function.

func (*GoRenderer[T]) L added in v0.7.0

func (r *GoRenderer[T]) L(line string, a ...any)

L renders text line using given format and puts it into the buffer.

Usage example:

r.Let("dst", "buf")
r.L(`$dst = append($dst, $0)`, 12)

Will render:

buf = append(buf, 12)

func (*GoRenderer[T]) Let added in v0.12.2

func (r *GoRenderer[T]) Let(name string, value any)

Let adds a named constant into the scope of the renderer. It will panic if you will try to set a different value for the existing name.

func (*GoRenderer[T]) M added in v0.17.0

func (r *GoRenderer[T]) M(rcvr ...any) func(name string) func(params ...any) *GoFuncRenderer[T]

M method definition rendering helper. rcvr must be one of:

  • single string
  • single fmt.Stringer
  • single *types.Var
  • single types.Type
  • single ast.Type
  • a string or fmt.Stringer followed by an any option above except *types.Var.

The return value is a function with a signature whose semantics matches F.

So, the usage of this method will be like

r.M("t", "*Type")("Name")("ctx $ctx.Context").Returns("string", "error, "").Body(func(…) {
    r.L(`return $ZeroReturnValue $errs.New("error")`)
})

Producing this code

func (t *Type) Name(ctx context.Context) (string, error) {
    return "", errors.New("error")
}

func (*GoRenderer[T]) N added in v0.7.0

func (r *GoRenderer[T]) N()

N puts the new line character into the buffer.

func (*GoRenderer[T]) Object added in v0.19.0

func (r *GoRenderer[T]) Object(item types.Object) string

Object renders fully qualified object name.

func (*GoRenderer[T]) PkgObject added in v0.19.0

func (r *GoRenderer[T]) PkgObject(pkgRef any, name string) string

PkgObject renders fully qualified object name used with the referenced package. The reference can be done with one of:

  • *types.Named.
  • types.Object.
  • *GoRenderer[T].
  • string containing package path.

func (*GoRenderer[T]) Proto added in v0.7.0

func (r *GoRenderer[T]) Proto(t ast.Type) ProtocType

Proto renders protoc-gen-go generated name based on protoast protobuf types representation. Provides the same guarantees as Type, i.e. imports, package qualifiers, etc.

func (*GoRenderer[T]) R added in v0.7.0

func (r *GoRenderer[T]) R(line string)

R puts raw text without formatting into the buffer.

func (*GoRenderer[T]) S added in v0.7.0

func (r *GoRenderer[T]) S(line string, a ...any) string

S same as L but returns string instead of buffer write.

func (*GoRenderer[T]) Scope added in v0.10.0

func (r *GoRenderer[T]) Scope() (res *GoRenderer[T])

Scope returns a new renderer with a scope inherited from the original. Any scope changes made with this renderer will not reflect into the scope of the original renderer.

func (*GoRenderer[T]) SetReturnZeroValues added in v0.18.1

func (r *GoRenderer[T]) SetReturnZeroValues(values ...string)

SetReturnZeroValues adds a named constant with the ReturnZeroValues name whose role is to represent zero return values in functions.

Usage example:

r.Imports.Add("io").Manager("io")
r.Imports.Add("errors").Manager("errs")
r.F("file")("name", "string").Returns("*$io.ReadCloser", "error", "").Body(func(r *Go) {
    r.L(`// Look at trailing comma, it is important ... $ReturnZeroValues`)
    r.L(`return $ReturnZeroValues $errs.New("error")`)
})

Output:

func file(name string) (io.ReadCloser, error) {
    // Look at trailing comma, it is important ... nil,
    return nil, errors.New("error"
}

Take a look at the doc to know more about how results and parameters can be set up.

This example may look weird and actually harder to write than a simple formatting, but it makes a sense in fact when we work upon the existing source code, with these types.Type everywhere. You don't even need to set up this constant manually with them BTW, it will be done for you based on return types provided by the Returns call itself.

This value can be overriden BTW.

func (*GoRenderer[T]) T added in v0.20.0

func (r *GoRenderer[T]) T() *GoRenderer[T]

T produces a temporary renderer which renders for the same package but will not save its content anywhere. It is meant to deal with side effects caused by Type, PkgObject, Object, Proto and alike – – they do imports for the file generated with this renderer.

func (*GoRenderer[T]) Taken added in v0.14.0

func (r *GoRenderer[T]) Taken(name string) bool

Taken checks if the given unique name has been taken before.

func (*GoRenderer[T]) TryLet added in v0.16.0

func (r *GoRenderer[T]) TryLet(name string, value any)

TryLet same as Let but without a panic, it just exits when the variable is already there.

func (*GoRenderer[T]) Type added in v0.7.0

func (r *GoRenderer[T]) Type(t types.Type) string

Type renders fully qualified type name based on go/types representation. You don't need to care about importing a package this type defined in or to use package name to access a type. This method will do this all.

Beware though, the produced code may be incorrect if your type names are only used in strings or comments. You will have an import statement for them, but won't use them at the same time.

func (*GoRenderer[T]) Uniq added in v0.10.0

func (r *GoRenderer[T]) Uniq(name string, optSuffix ...string) string

Uniq is used to generate unique names, to avoid variables names clashes in the first place. This is how it works:

r.Uniq("name")        // name
r.Uniq("name")        // name1
r.Uniq("name")        // name2
r.Uniq("name", "alt") // nameAlt
r.Uniq("name", "alt") // name3
r.Uniq("name", "opt") // nameOpt

Remember, Uniq's name and Let's key have nothing in common.

func (*GoRenderer[T]) Z added in v0.7.0

func (r *GoRenderer[T]) Z() (res *GoRenderer[T])

Z provides a renderer instance of "laZy" writing.

What it does:

  1. Inserts a new text block and switches the current renderer to it.
  2. Return a new renderer which references a block which was the current before.

So, with this renderer you will write into the previous "current", while the original renderer will write into the next. This means you will have text rendered with the returned GoRenderer instance will appear before the one made with the original renderer after the Z call. Even if writes with the original were made before the writes with the returned.

Example:

r.R(`// Hello`)
x := r.Z()
r.R(`// World!`)
x.R(`// 你好`)

Output:

// Hello
// 你好
// World!

See, even though we wrote Chinese("Hello") after the "World!" it appears before it after the rendering.

type ImportAliasControl added in v0.7.0

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

ImportAliasControl allows to assign an alias for package import

func (*ImportAliasControl) As added in v0.7.0

As assign given alias for the import. Conflicting one may cause a panic.

func (*ImportAliasControl) Ref added in v0.7.0

func (a *ImportAliasControl) Ref(ref string)

Ref adds a package name or alias into the renderingOptionsHandler's context under the given name ref

type ImportReferenceControl added in v0.7.0

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

ImportReferenceControl allows to add a variable having package name (or alias) in the renderingOptionsHandler scope

func (*ImportReferenceControl) Ref added in v0.7.0

func (r *ImportReferenceControl) Ref(ref string)

Ref adds a package name or alias into the renderering context under the given name ref

type Importer added in v0.7.0

type Importer interface {
	Add(pkgpath string) *ImportAliasControl
	Module(relpath string) *ImportAliasControl
	Imports() *Imports
}

Importer an abstraction for Imports extensions

type Imports

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

Imports a facility to add imports in the GoFile source file

func (*Imports) Add

func (i *Imports) Add(pkgpath string) *ImportAliasControl

Add registers new import if it wasn't before.

func (*Imports) Imports added in v0.7.0

func (i *Imports) Imports() *Imports

Imports to satisfy Importer

func (*Imports) Module added in v0.7.0

func (i *Imports) Module(relpath string) *ImportAliasControl

Module to import a package placed with the current module

type L added in v0.17.0

type L string

L means "literal" and is intended to be used when raw strings are to be represented as quoted string literals while fmt.Stringer-s are to keep their original values.

func (L) String added in v0.17.0

func (l L) String() string

type Module added in v0.7.0

type Module[T Importer] struct {
	// contains filtered or unexported fields
}

Module all code generation is done within a module.

func New added in v0.7.0

func New[T Importer](
	formatter Formatter,
	importer func(r *Imports) T,
	opts ...ModuleOption[T],
) (*Module[T], error)

New computes GoFile module data and creates an instance of Module

func (*Module[T]) Current added in v0.10.0

func (m *Module[T]) Current(name string) (*Package[T], error)

Current create a package places in the current directory. The name parameter is rather optional and will be replaced if there are existing Go files in the package.

func (*Module[T]) GetDependency added in v0.10.0

func (m *Module[T]) GetDependency(path, version string) error

GetDependency adds the dependency at the given version to the module

func (*Module[T]) GetDependencyLatest added in v0.10.0

func (m *Module[T]) GetDependencyLatest(path string) error

GetDependencyLatest adds the latest version of the dependency to the module

func (*Module[T]) Name added in v0.7.0

func (m *Module[T]) Name() string

Name returns module name

func (*Module[T]) Package added in v0.7.0

func (m *Module[T]) Package(name, pkgpath string) (*Package[T], error)

Package creates if needed and returns a subpackage of the project root. The pkgpath parameter can be relative to the module or to be a full package path, including module name as well. This will be handled. The name parameter is rather optional and will be replaced if there are existing Go files in the package.

func (*Module[T]) PackageName added in v0.10.0

func (m *Module[T]) PackageName(pkgpath string) (string, error)

PackageName returns package name if it does exist, returns empty string otherwise. props parameter may

func (*Module[T]) Raw added in v0.8.0

func (m *Module[T]) Raw(relpath string, opts ...RendererOption) *RawRenderer

Raw creates a renderer for plain text file

func (*Module[T]) Render added in v0.7.0

func (m *Module[T]) Render() error

Render renders generated data

func (*Module[T]) Root added in v0.7.0

func (m *Module[T]) Root(name string) (*Package[T], error)

Root create if needed and returns a package placed right in the project root. The name parameter is rather optional and will be replaced if there are existing Go files in the package.

type ModuleOption added in v0.7.0

type ModuleOption[T Importer] func(_ hiddenType, m *Module[T])

ModuleOption module option

func WithAliasCorrector added in v0.7.0

func WithAliasCorrector[T Importer](corrector AliasCorrector) ModuleOption[T]

WithAliasCorrector sets alias corrector for all GoRenderers to be created

func WithFixedDeps added in v0.10.0

func WithFixedDeps[T Importer](deps map[string]semver.Version) ModuleOption[T]

WithFixedDeps sets dependencies whose versions must have a specific version

type Package added in v0.7.0

type Package[T Importer] struct {
	// contains filtered or unexported fields
}

Package represents a package of the current module

func (*Package[T]) Go added in v0.7.0

func (p *Package[T]) Go(name string, opts ...RendererOption) (res *GoRenderer[T])

Go creates new or reuse existing Go source file renderer, options may alter code generation.

func (*Package[T]) Package added in v0.7.0

func (p *Package[T]) Package(name, pkgpath string) (*Package[T], error)

Package creates "subpackage" of the current package

func (*Package[T]) Path added in v0.7.0

func (p *Package[T]) Path() string

Path returns package path

func (*Package[T]) Raw added in v0.9.0

func (p *Package[T]) Raw(name string, opts ...RendererOption) *RawRenderer

Raw creates new or reuse existing plain text file renderer.

func (*Package[T]) Reuse added in v0.12.0

func (p *Package[T]) Reuse(name string) (result *GoRenderer[T], _ error)

Reuse creates a renderer over existing file if it exists. Works as Go without options otherwise.

func (*Package[T]) Void added in v0.13.0

func (p *Package[T]) Void() *GoRenderer[T]

Void creates a Go renderer for a file in the current package that will not be saved on the Modules' Render call and won't have any kind of footprint.

type Params added in v0.4.0

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

Params parameters list

func (*Params) Add added in v0.10.0

func (p *Params) Add(name, typ string) *Params

Add adds new parameter

func (*Params) Multi added in v0.10.0

func (s *Params) Multi() string

Multi returns a parameters text representation written in one per line

func (Params) String added in v0.4.0

func (s Params) String() string

String returns a line of comma-separated entities

type ProtocType added in v0.7.0

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

ProtocType сущность для различных сценариев использования сгенерированного protoc-gen-go типа

func (ProtocType) Impl added in v0.7.0

func (s ProtocType) Impl() string

Impl используемый тип (добавляется указатель, если proto.Message реализуется на указателе на значение типа)

func (ProtocType) Local added in v0.7.0

func (s ProtocType) Local() string

Local локальное имя сгенерированного типа

func (ProtocType) LocalImpl added in v0.7.0

func (s ProtocType) LocalImpl() string

LocalImpl локальный используемый тип (добавляется указатель, если proto.Message реализуется на указателе на значение типа)

func (ProtocType) Pkg added in v0.7.0

func (s ProtocType) Pkg() string

Pkg возвращает название пакета

func (ProtocType) String added in v0.7.0

func (s ProtocType) String() string

String имя сгенерированного типа

type Q added in v0.17.0

type Q string

Q is a shortcut to write string values as Go source code strings.

func (Q) String added in v0.17.0

func (q Q) String() string

type RawRenderer added in v0.8.0

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

RawRenderer rendering of plain text files

func (*RawRenderer) L added in v0.8.0

func (r *RawRenderer) L(line string, a ...any)

L puts a single formatted line and new line character

func (*RawRenderer) N added in v0.8.0

func (r *RawRenderer) N()

N puts new line character

func (*RawRenderer) Put added in v0.22.0

func (r *RawRenderer) Put(data []byte)

Put puts raw bytes directly.

func (*RawRenderer) R added in v0.8.0

func (r *RawRenderer) R(line string)

R puts unformatted line and new line character

func (*RawRenderer) S added in v0.8.0

func (r *RawRenderer) S(line string, a ...any) string

S same as L, just returns string insert of pushing it

func (*RawRenderer) Z added in v0.8.0

func (r *RawRenderer) Z() *RawRenderer

Z returns extended RawRenderer which will write after the last written line of the current one and before any new line pushed after this call.

type RendererOption added in v0.8.0

type RendererOption func(r renderingOptionsHandler) bool

RendererOption an option to be applied before the rendering

func Autogen added in v0.7.0

func Autogen(appname string) RendererOption

Autogen puts header `Code generated by <app name> version vX.Y.Z. DO NOT EDIT.`

func WithValue added in v0.8.0

func WithValue(name string, value any) RendererOption

WithValue shortcut for WithValues with the single named value

func WithValues added in v0.8.0

func WithValues(vals map[string]any) RendererOption

WithValues puts given named values into the rendering context

Directories

Path Synopsis
cmd
mimchain/internal/testexample
Package testexample is a testing playground for mimchain
Package testexample is a testing playground for mimchain
internal
blocks
Package block provides an ordered sequence of buffers
Package block provides an ordered sequence of buffers
heuristics
Package heuristics provides guessing on text value representation.
Package heuristics provides guessing on text value representation.
test
Package reuse to dig into ASTs.
Package reuse to dig into ASTs.

Jump to

Keyboard shortcuts

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