Documentation
¶
Overview ¶
Package codegen generates Go source from a resolved AST.
Uses dst (formatting-preserving Go AST) - preserved from the POC. Produces the main.go that statically links all imports (Go libraries and UB libraries). Embeds the source body and library-path so the binary self-reports its identity; the version and content-revision are stamped in at link time. UB libraries are inlined as expanded sub-DAGs (composite types decompose into internal resources at code-gen time).
Output is a complete Go module that the Go toolchain compiles into the stack binary.
Index ¶
- func ContentRevision(dir string) (string, error)
- func EncodeNode(n lang.Node) (string, error)
- func Generate(in Input) ([]byte, error)
- func GenerateUBLibrary(alias string, bodies map[string]*lang.File, kinds map[string]string, ...) ([]byte, error)
- func WriteSource(dir string, in Input, goVersion, unobinVersion string, ...) error
- type GoLibrarySpecs
- type Input
- type Replaces
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ContentRevision ¶
ContentRevision returns a short content-addressable revision for the generated library in dir. It hashes every Go source file plus go.mod and go.sum in sorted path order, so the result is a stable fingerprint of the stack source, the inlined UB libraries, and the full pinned Go dependency set that go.sum records. The compiled binary itself is excluded; only build inputs contribute. Run it after `go mod tidy` so go.sum is present.
func EncodeNode ¶
EncodeNode renders a parsed `lang` AST node as a Go expression that constructs an equivalent value. The expression evaluates to the matching `lang` pointer type (`*lang.File` for a File, `*lang.Field` for a Field, the matching `*lang.X` for any expression node).
Source positions are not encoded; the produced node has zero Span values. The encoder handles every plain expression node and every `TypeExpr` node; callers must not pass a node kind the parser does not produce as part of a body.
func Generate ¶
Generate produces the formatted Go source for the factory binary's main.go. The result is the bytes a caller writes to disk and feeds through `go build`.
func GenerateUBLibrary ¶
func GenerateUBLibrary(alias string, bodies map[string]*lang.File, kinds map[string]string, imports map[string]map[string]string, goSpecs map[string]GoLibrarySpecs) ([]byte, error)
GenerateUBLibrary produces the Go source for a UB library's generated package. The package's name is alias; it exports a `Library()` function returning a `*runtime.Library` whose composites are split into one map per kind (ResourceComposites, DataComposites, ActionComposites). bodies and kinds are both keyed by composite type name (derived from each file's `<kind>-<type>.ub` name); kinds gives the kind.
imports maps each composite's type name to its resolved import table: the composite's body's own imports block, with each declared alias mapped to the Go import path of the package that supplies it. The generated source emits one Go-level import per unique path and renders a per-composite `Libraries` map binding each composite-local alias to the corresponding package's `Library()`. Pass nil or an empty map when a composite has no imports.
goSpecs maps a Go import path to the specs its types declare. A bound library with specs is constructed once in `Library()`, has its Constraints and Defaults attached, and every binding of that path shares the instance, so a composite-internal node resolves the same spec data a root import of the library would.
func WriteSource ¶
func WriteSource( dir string, in Input, goVersion, unobinVersion string, importVersions map[string]string, replaces Replaces, ) error
WriteSource lays out a stack binary's source tree in dir, ready for `go build` to consume. It writes:
<dir>/main.go // From Generate. <dir>/go.mod // With the right require statements.
goVersion is the Go toolchain version to declare. unobinVersion is the version of `github.com/cloudboss/unobin` the generated binary depends on. importVersions maps each library's Go import path to the version constraint to require. replaces maps a library path to a local path to substitute via `replace`.
Types ¶
type GoLibrarySpecs ¶ added in v0.6.0
type GoLibrarySpecs struct {
Constraints map[string][]lang.ConstraintSpec
Defaults map[string][]lang.DefaultSpec
}
GoLibrarySpecs holds one Go library's compile-extracted spec data, keyed by "<kind>.<type>" the way runtime.Library stores it. The dev CLI gathers it from the library's source; codegen embeds it in generated code so the runtime can look it up at plan and apply.
func (GoLibrarySpecs) Empty ¶ added in v0.6.0
func (s GoLibrarySpecs) Empty() bool
Empty reports whether the specs hold no data at all.
type Input ¶
type Input struct {
Body string
LibraryPath string
FactoryName string
GoImports map[string]string
UBImports map[string]string
// GoConstraints maps a Go-library alias to its types' cross-field
// constraints (kebab type name -> specs), gathered by the dev CLI
// from the library's source. codegen attaches them to the library in
// the generated main.go so the plan can check each node against them.
GoConstraints map[string]map[string][]lang.ConstraintSpec
// GoDefaults maps a Go-library alias to its types' declared input
// defaults, gathered the same way and attached the same way, so the
// runtime can fill them into evaluated bodies.
GoDefaults map[string]map[string][]lang.DefaultSpec
}
Input bundles everything codegen needs to produce a factory binary's `main.go`. Body is the literal factory source the binary embeds and parses on each invocation. LibraryPath is the binary's library-path identity, the same form Go libraries use; the operator's `config.ub` asserts the same value under `factory.pin.library-path` and plan, refresh, and validate refuse on mismatch. An empty LibraryPath disables that identity check. The version and content-revision are not generated here; compile stamps them into the built binary with -ldflags so the generated source stays a pure function of the factory content. GoImports maps each Go-library alias the source uses to the Go import path that supplies it (e.g., `"core" -> "github.com/cloudboss/unobin/pkg/libraries/core"`). UBImports maps each UB-library alias to the local Go import path of the package that compile generated for it (typically `<factory-name>/internal/<alias>`).