gen

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jul 16, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package gen defines the directive contract and render tree for main.gen.go.

Directive lifecycle

A directive parses annotations, validates typed targets, and emits nodes. Meta declares syntax, docs, completions, and emission tier.

The generation tree

Emit appends typed nodes such as ConfigLoad, Call, StructLit, Select, Route, Serve, and Assign. Raw holds preformatted lines when no typed node fits. Base records origin, phase, optional label, and manual dependencies.

Rendering policies

The renderer groups nodes by phase, keeps dependency clusters contiguous, orders independent clusters by source anchor, and emits deterministic Go.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func EmbedCovers

func EmbedCovers(a Annotation, pattern string) (found, covered bool)

EmbedCovers scans the annotation's comment group for //go:embed lines. found reports whether any exists; covered reports whether one of their patterns equals pattern. Directives anchored to embed.FS variables use it to require the all: form, wording their own diagnostics.

func EnsureStruct

func EnsureStruct(g *Gen, fset *token.FileSet, t types.Type) (string, diag.Diagnostics)

EnsureStruct returns the wired expression for a handler struct.

func IsContext

func IsContext(t types.Type) bool

IsContext reports whether t is context.Context.

func LowerFirst

func LowerFirst(s string) string

LowerFirst lowercases the leading rune, for deriving generated identifiers from exported Go names.

func RegisterStruct

func RegisterStruct(g *Gen, fset *token.FileSet, t types.Type)

RegisterStruct lazily registers construction for a pointer-to-named struct. Existing bindings win.

Types

type Annotation

type Annotation struct {
	Name    string         // keyword after //fabrik:
	Args    string         // raw text after the keyword
	Pos     token.Position // position of the directive comment
	ArgsCol int            // column where Args starts on the directive line
	Decl    ast.Node       // annotated declaration: *ast.FuncDecl or *ast.TypeSpec
	Doc     []string       // every line of the enclosing comment group, verbatim
}

Annotation is the syntactic view of one directive comment.

func (Annotation) ArgPos

func (a Annotation) ArgPos(col int) token.Position

ArgPos returns the source position for an offset within Args.

type Arg

type Arg struct {
	Text string
	Col  int // byte offset within Annotation.Args
}

Arg is one token from directive arguments.

type Args

type Args struct {
	Pos  []Arg
	Attr map[string]Arg
}

Args contains positional arguments and key=value options.

func ParseArgs

func ParseArgs(a Annotation, m Meta) (Args, diag.Diagnostics)

ParseArgs applies Meta's argument shape without validating value semantics.

type Assign

type Assign struct {
	Base
	Var  string
	Expr string
}

Assign declares a variable from an expression: `v := expr`.

type AttrSpec

type AttrSpec struct {
	Key      string
	Kind     ValueKind
	Values   []string // completion candidates; a closed set only when Kind is KindEnum
	Required bool
}

AttrSpec describes one key=value option.

type Base

type Base struct {
	Origin Origin
	Phase  Phase    // run() section; child nodes inherit their parent's phase
	Label  string   // optional one-line comment above the node
	Uses   []string // manual dependency additions; rendered text supplies the rest
}

Base is shared node metadata.

type Call

type Call struct {
	Base
	Var  string // assigned variable; "" for a bare call
	Fn   string // rendered callee, e.g. "shared.InitLogger" or "r.Use"
	Args []string
	Err  ErrStyle
}

Call invokes a constructor or registration function.

type Case

type Case struct {
	Value  string
	Body   []Node // e.g. branch-local config loads
	Result Call   // Var set when the constructor returns an error
}

Case is one selection arm: branch-local work, then the constructor.

type ConfigLoad

type ConfigLoad struct {
	Base
	Var     string
	Pkg     string   // config package alias
	Type    string   // rendered struct type
	Options []string // rendered option expressions
}

ConfigLoad loads one configuration struct.

type Directive

type Directive interface {
	Name() string
	Meta() Meta
	Parse(Annotation) (any, diag.Diagnostics)
	Check(node any, t Typed) diag.Diagnostics
	Emit(node any, g *Gen) diag.Diagnostics
}

Directive implements one //fabrik:NAME annotation.

type EmitTier

type EmitTier int

EmitTier orders directive emission.

const (
	TierMain EmitTier = iota // resolve dependencies and emit (the default)
	TierBind                 // registration only: bind values, resolve nothing
	TierHook                 // lifecycle hooks: bindings exist, nothing resolved yet
)

type ErrStyle

type ErrStyle int

ErrStyle says how a call's error result is handled.

const (
	ErrNone   ErrStyle = iota // no error result
	ErrReturn                 // v, err := call; if err != nil { return err }
	ErrInline                 // if err := call; err != nil { return err }
)

type Field

type Field struct {
	Name, Expr string
}

Field is one injected struct field.

type Finisher

type Finisher interface {
	Finish(g *Gen) diag.Diagnostics
}

Finisher runs after all nodes emit and may append more code.

type Gen

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

Gen assembles main.gen.go from imports, DI bindings, and phased statements.

func New

func New() *Gen

New returns an empty Gen.

func (*Gen) AddMissingHint

func (g *Gen) AddMissingHint(f func(types.Type) (string, bool))

AddMissingHint registers a missing-binding help source.

func (*Gen) Bind

func (g *Gen) Bind(t types.Type, name, expr string)

Bind records expr as the wired value for (t, name).

func (*Gen) BindLazy

func (g *Gen) BindLazy(t types.Type, name string, build func() (string, diag.Diagnostics))

BindLazy registers a value that is emitted on first resolution.

func (*Gen) BindLazyPath

func (g *Gen) BindLazyPath(path string, build func() (string, diag.Diagnostics))

BindLazyPath registers a lazy binding matched by a printed type path.

func (*Gen) BindPath

func (g *Gen) BindPath(path, expr string)

BindPath publishes an expression while its lazy path binding is materializing.

func (*Gen) Context

func (g *Gen) Context() string

Context marks the lifecycle context as needed and returns its variable; Render emits the assignment as run()'s first statement.

func (*Gen) HasBinding

func (g *Gen) HasBinding(t types.Type, name string) bool

HasBinding reports whether (t, name) has an eager or lazy binding, without materializing anything.

func (*Gen) HasBindingPath

func (g *Gen) HasBindingPath(path string) bool

HasBindingPath reports whether a path-keyed binding exists, lazy or already materialized.

func (*Gen) HasProviderBinding

func (g *Gen) HasProviderBinding(t types.Type, name string) bool

HasProviderBinding reports whether (t, name) has a provider-owned lazy binding, excluding library path bindings.

func (*Gen) HasSingleton

func (g *Gen) HasSingleton(key string) bool

HasSingleton reports whether key has been created.

func (*Gen) Import

func (g *Gen) Import(path string) string

Import records an import and returns its stable alias.

func (*Gen) ImportPkg

func (g *Gen) ImportPkg(p *types.Package) string

ImportPkg imports a typed package by its declared name.

func (*Gen) Instance

func (g *Gen) Instance(t types.Type, name string) (string, diag.Diagnostics, bool)

Instance resolves the wired expression for (t, name).

func (*Gen) InstancePath

func (g *Gen) InstancePath(path string) (string, diag.Diagnostics, bool)

InstancePath resolves a path-keyed lazy binding.

Diagnosed path builds are not cached.

func (*Gen) LookupType

func (g *Gen) LookupType(pkgPath, name string) (types.Type, bool)

LookupType returns a named type from a type-checked imported package.

func (*Gen) MissingHint

func (g *Gen) MissingHint(t types.Type) (string, bool)

MissingHint returns the first domain help that applies to t.

func (*Gen) Module

func (g *Gen) Module() string

Module returns the module path of the app being generated.

func (*Gen) Node

func (g *Gen) Node(n Node)

Node appends n and fills a missing directive origin.

func (*Gen) Render

func (g *Gen) Render() ([]byte, error)

Render assembles and formats main.gen.go.

func (*Gen) SetDirective

func (g *Gen) SetDirective(name string)

SetDirective records the directive currently emitting code.

func (*Gen) SetModule

func (g *Gen) SetModule(path string)

SetModule records the module path of the app being generated.

func (*Gen) SetTypes

func (g *Gen) SetTypes(m map[string]*types.Package)

SetTypes supplies type-checked packages for Gen.LookupType.

func (*Gen) Singleton

func (g *Gen) Singleton(key, varName, ctor string) string

Singleton returns the shared variable for key, emitting it on first use.

func (*Gen) SingletonIn

func (g *Gen) SingletonIn(phase Phase, key, varName, ctor string) string

SingletonIn emits the shared variable in a specific phase.

func (*Gen) Stmt

func (g *Gen) Stmt(phase Phase, format string, a ...any)

Stmt appends a Raw node.

func (*Gen) TypeExpr

func (g *Gen) TypeExpr(t types.Type) string

TypeExpr renders t and imports every package it mentions.

func (*Gen) Var

func (g *Gen) Var(base string) string

Var reserves a unique identifier derived from base.

type Hinter

type Hinter interface {
	MissingHint(t types.Type) (string, bool)
}

Hinter improves missing-binding diagnostics with domain-specific help.

type Meta

type Meta struct {
	Synopsis string     // one line, shown as completion detail
	Doc      string     // markdown, shown on hover
	Example  string     // usage shown in diagnostics help
	Pos      []PosSpec  // required positional arguments, in order
	Attrs    []AttrSpec // key=value options
	Tier     EmitTier   // when Emit runs relative to other directives
}

Meta describes directive syntax, docs, completions, and lifecycle.

type Node

type Node interface {
	// contains filtered or unexported methods
}

Node is one emission in the generation tree.

type NodePreparer

type NodePreparer interface {
	PrepareNode(node any, g *Gen)
}

NodePreparer registers bindings before dependency resolution.

type Origin

type Origin struct {
	Directive string
	Pos       token.Position
}

Origin ties a node to the directive occurrence that produced it.

type Parsed

type Parsed struct {
	Directive Directive
	Node      any
}

Parsed pairs a node with the directive that produced it.

type Phase

type Phase int

Phase orders generated statements inside run().

const (
	PhaseConfig     Phase = iota // configuration loading, before all else
	PhaseSetup                   // setup hooks: config exists, providers do not
	PhaseWire                    // construct app and runtime values
	PhaseMiddleware              // global middleware registration
	PhaseRegister                // register generated behavior onto constructed values
	PhasePrepare                 // prepare hooks: pre-intake work on registered resources
	PhaseStart                   // start hooks: start background runtime processes
	PhaseServe                   // start serving, ending with return
)

type PosSpec

type PosSpec struct {
	Name     string    // e.g. "METHOD"; used in messages and docs
	Kind     ValueKind // completion hint; values are validated by Parse
	Values   []string  // completion candidates; a closed set only when Kind is KindEnum
	Optional bool
}

PosSpec describes one positional argument.

type Raw

type Raw struct {
	Base
	Lines   []string
	Defines []string // variables the lines declare, for dependency ordering
}

Raw is a preformatted emission.

type Route

type Route struct {
	Base
	Router  string
	Kind    RouteKind
	Method  string
	Pattern string
	Handler string   // rendered handler expression
	Chain   []string // middleware expressions, outermost first
}

Route registers one route on the router.

type RouteKind

type RouteKind int

RouteKind distinguishes route registration forms.

const (
	RouteMethod     RouteKind = iota // Router.Method(m, p, handler, chain...)
	RouteHandle                      // Router.Handle(p, chain-wrapped handler)
	RouteHandleFunc                  // Router.HandleFunc(p, handler)
)

type Select

type Select struct {
	Base
	Var     string // the interface variable being assigned
	Iface   string // rendered interface type
	KeyExpr string // e.g. "webConfig.Kind"
	FmtPkg  string // fmt alias, for the unmatched-value arm
	Cases   []Case
}

Select wires the implementation a configuration value names.

type Serve

type Serve struct {
	Base
	Expr string
}

Serve returns from run with the serving call.

type StructLit

type StructLit struct {
	Base
	Var    string
	Type   string // rendered struct type, without the &
	Fields []Field
}

StructLit constructs a pointer to a struct with injected fields.

type Typed

type Typed struct {
	Target types.Object   // the annotated func/method/type, fully typed
	Fset   *token.FileSet // resolves positions of typed objects
}

Typed is the semantic view of an annotation.

type Validator

type Validator interface {
	Validate(g *Gen) diag.Diagnostics
}

Validator observes completed generation without emitting code.

type ValueKind

type ValueKind int

ValueKind classifies completion behavior for argument values.

const (
	KindFreeform ValueKind = iota
	KindEnum
	KindMiddlewareRef // completes from declared //fabrik:http:middleware names
)

Jump to

Keyboard shortcuts

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