From 01a60d06f1d6dc4ffb2c3b63fc88c8337928fbb8 Mon Sep 17 00:00:00 2001 From: Lilleman auf Larv Date: Mon, 28 Sep 2026 10:37:26 +0200 Subject: [PATCH] Name the inline drawGroup refusal as a binding's reference fence, beside the cycle fence --- data.go | 23 ++++++++--------------- docs/decisions.md | 3 ++- inline.go | 17 +++++++++-------- 3 files changed, 19 insertions(+), 24 deletions(-) diff --git a/data.go b/data.go index 46c9cda..52e94ec 100644 --- a/data.go +++ b/data.go @@ -200,14 +200,10 @@ func inlineScope(n node, label string) nodeScope { // NewTemplate and FakeStruct share; its fields are where they differ. type binding struct { scope nodeScope - // link binds the references: a loaded tree's relative to each category's folder, an - // inline node's from the root alone. - link func() error - // noCycles refuses a reference cycle, which only a loaded tree can close: nothing - // references an inline node. - noCycles func() error - // typedByGo marks a struct's columns, whose datatypes its Go types set and checkField - // proves, so checkColumns skips them. + link func() error + // A loaded tree's cycle fence; an inline node's refusal of a drawGroup at its root. + referenceFence func() error + // checkField proves a struct's columns instead. typedByGo bool } @@ -221,7 +217,7 @@ func treeBinding(root map[string]node) binding { } return linkRefs(root) }, - noCycles: func() error { return checkNoCycles(root) }, + referenceFence: func() error { return checkNoCycles(root) }, } } @@ -229,10 +225,8 @@ func (b binding) bind() error { if err := b.link(); err != nil { return err } - if b.noCycles != nil { - if err := b.noCycles(); err != nil { - return err - } + if err := b.referenceFence(); err != nil { + return err } if !b.typedByGo { if err := checkColumns(b.scope); err != nil { @@ -244,8 +238,7 @@ func (b binding) bind() error { // checkRenders runs the per-node fences over a scope, each over the whole scope // before the next, so which of several broken nodes is reported does not depend on -// the walk. Its walks terminate only where nothing renders itself, so run it over a -// loaded tree after checkNoCycles. +// the walk. Its walks terminate only where nothing renders itself. func checkRenders(s nodeScope) error { mem := renderCounts{} if err := s(func(path string, n node) error { return repeatCheck(path, n, mem) }); err != nil { diff --git a/docs/decisions.md b/docs/decisions.md index 1c697e6..3544f20 100644 --- a/docs/decisions.md +++ b/docs/decisions.md @@ -58,7 +58,8 @@ tags and any other caller read one. `New` proves the loaded tree acyclic, an inline node is a finite tree of its own, and nothing in the tree can reference it, so no render of it reaches itself. Every other fence runs over both, from one `binding.bind`, except that struct tags leave column -agreement to their Go types. +agreement to their Go types, and an inline node refuses a `drawGroup` at its root, +which nothing can name. ## An inline template that does not compile is misuse (exit 2), including a reference that resolves to nothing diff --git a/inline.go b/inline.go index 29ecf11..3685670 100644 --- a/inline.go +++ b/inline.go @@ -146,17 +146,18 @@ func inputValue(input string) (any, error) { return raw, nil } -// inlineBinding binds an inline node against root, naming its nodes from label. func inlineBinding(n node, label string, root map[string]node) binding { scope := inlineScope(n, label) - return binding{scope: scope, link: func() error { return linkInline(n, label, scope, root) }} -} - -func linkInline(n node, label string, scope nodeScope, root map[string]node) error { - if t, isTemplate := n.(*template); isTemplate && t.drawGroup != "" { - return fmt.Errorf("%s: drawGroup %q names nothing, since nothing can reference an inline template; drop it", label, t.drawGroup) + return binding{ + scope: scope, + link: func() error { return linkNodeRefs(scope, root) }, + referenceFence: func() error { + if t, isTemplate := n.(*template); isTemplate && t.drawGroup != "" { + return fmt.Errorf("%s: drawGroup %q names nothing, since nothing can reference an inline template; drop it", label, t.drawGroup) + } + return nil + }, } - return linkNodeRefs(scope, root) } // linkNodeRefs binds the references in an inline node's templates against the