Give render and the draw fences one pin set
This commit is contained in:
@@ -127,27 +127,27 @@ func names(segs []string) []string {
|
||||
|
||||
// pathWalk is what one walk of a dotted path does at each kind of level: choice
|
||||
// returns the variants to continue into (none stops the walk), and where it is nil
|
||||
// the walk draws one with the pins' session, or stops; level runs at each template
|
||||
// a segment descends into; leaf runs where the tail ends; pins is where the walk
|
||||
// pins the table rows it selects and draws, nil skipping tables. A nil action is
|
||||
// skipped. A render's walk sets only pins, so it allocates nothing.
|
||||
// the walk draws one, or stops; level runs at each template a segment descends
|
||||
// into; leaf runs where the tail ends; pins is where the walk pins the table rows
|
||||
// it selects and draws, nil skipping tables. A nil action is skipped. A render's
|
||||
// walk sets only pins, so it allocates nothing.
|
||||
type pathWalk struct {
|
||||
choice func(c *choice, rest []string) ([]node, error)
|
||||
level func(t *template, rest []string) error
|
||||
leaf func(n node) error
|
||||
pins *hold
|
||||
pins *pinSet
|
||||
}
|
||||
|
||||
// walkPath descends tail from n and returns the node it ends at: a folder or
|
||||
// template by its next segment, a choice by w.choice, which consumes no segment, a
|
||||
// table by walkTable. A missing segment is an error, so no walk reaches past what
|
||||
// the data holds.
|
||||
func walkPath(n node, tail []string, w pathWalk) (node, error) {
|
||||
// the data holds. s draws rows and variants; nil, the walk only proves the path.
|
||||
func walkPath(s *session, n node, tail []string, w pathWalk) (node, error) {
|
||||
if len(tail) == 0 {
|
||||
return n, w.atLeaf(n)
|
||||
}
|
||||
if t, isTable := n.(*table); isTable {
|
||||
return walkTable(t, tail, w, false)
|
||||
return walkTable(s, t, tail, w, false)
|
||||
}
|
||||
if isSelector(tail[0]) {
|
||||
return nil, fmt.Errorf("%s is not a table, so it has no row to select", selectorOf(tail[0]))
|
||||
@@ -158,7 +158,7 @@ func walkPath(n node, tail []string, w pathWalk) (node, error) {
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("no entry %q", tail[0])
|
||||
}
|
||||
return walkPath(child, tail[1:], w)
|
||||
return walkPath(s, child, tail[1:], w)
|
||||
case *template:
|
||||
if w.level != nil {
|
||||
if err := w.level(n, tail); err != nil {
|
||||
@@ -169,9 +169,9 @@ func walkPath(n node, tail []string, w pathWalk) (node, error) {
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("no field %q", tail[0])
|
||||
}
|
||||
return walkPath(child, tail[1:], w)
|
||||
return walkPath(s, child, tail[1:], w)
|
||||
case *choice:
|
||||
return walkChoice(n, tail, w)
|
||||
return walkChoice(s, n, tail, w)
|
||||
case *column:
|
||||
return nil, fmt.Errorf("no field %q: %q is a column, and a cell holds no fields", tail[0], n.t.columns[n.i])
|
||||
}
|
||||
@@ -186,8 +186,8 @@ func (w pathWalk) atLeaf(n node) error {
|
||||
}
|
||||
|
||||
// walkChoice continues a walk into the variants w.choice returns, or into one drawn
|
||||
// by the pins' session where the walk names no choice action.
|
||||
func walkChoice(c *choice, tail []string, w pathWalk) (node, error) {
|
||||
// by s where the walk names no choice action.
|
||||
func walkChoice(s *session, c *choice, tail []string, w pathWalk) (node, error) {
|
||||
if w.choice == nil {
|
||||
if w.pins == nil {
|
||||
return nil, nil
|
||||
@@ -195,10 +195,10 @@ func walkChoice(c *choice, tail []string, w pathWalk) (node, error) {
|
||||
if err := carriedByAll(c, tail); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if w.pins.s == nil { // a probe: every variant carries the tail, so any one proves it
|
||||
return walkPath(c.items[0], tail, w)
|
||||
if s == nil { // a probe: every variant carries the tail, so any one proves it
|
||||
return walkPath(s, c.items[0], tail, w)
|
||||
}
|
||||
return walkPath(pick(w.pins.s, c), tail, w)
|
||||
return walkPath(s, pick(s, c), tail, w)
|
||||
}
|
||||
next, err := w.choice(c, tail)
|
||||
if err != nil {
|
||||
@@ -206,7 +206,7 @@ func walkChoice(c *choice, tail []string, w pathWalk) (node, error) {
|
||||
}
|
||||
var last node
|
||||
for _, item := range next {
|
||||
if last, err = walkPath(item, tail, w); err != nil {
|
||||
if last, err = walkPath(s, item, tail, w); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@@ -217,7 +217,7 @@ func walkChoice(c *choice, tail []string, w pathWalk) (node, error) {
|
||||
// linked table by name. The walk reads a row wherever a segment follows or the
|
||||
// table was reached from another; a table reached whole, with no selector, is left
|
||||
// to a render's own draw.
|
||||
func walkTable(t *table, tail []string, w pathWalk, descended bool) (node, error) {
|
||||
func walkTable(s *session, t *table, tail []string, w pathWalk, descended bool) (node, error) {
|
||||
sel, tail, err := t.selector(tail)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -229,19 +229,19 @@ func walkTable(t *table, tail []string, w pathWalk, descended bool) (node, error
|
||||
// A selector further down pins this table by ancestry, so the walk draws only
|
||||
// where none follows; drawing first could pick a row the selector is not inside.
|
||||
if w.pins != nil {
|
||||
if err := readRow(w.pins, t, sel, (descended || len(tail) > 0) && !hasSelector(tail)); err != nil {
|
||||
if err := readRow(s, w.pins, t, sel, (descended || len(tail) > 0) && !hasSelector(tail)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
switch {
|
||||
case len(tail) == 0 && sel == "" && !descended:
|
||||
return walkPath(t, nil, w)
|
||||
return walkPath(s, t, nil, w)
|
||||
case len(tail) == 0:
|
||||
return walkPath(t.whole, nil, w)
|
||||
return walkPath(s, t.whole, nil, w)
|
||||
case child != nil:
|
||||
return walkTable(child, tail[1:], w, true)
|
||||
return walkTable(s, child, tail[1:], w, true)
|
||||
}
|
||||
return walkPath(column, tail[1:], w)
|
||||
return walkPath(s, column, tail[1:], w)
|
||||
}
|
||||
|
||||
// selector splits the selector a tail starts with from the rest of it.
|
||||
@@ -272,12 +272,12 @@ func (t *table) step(tail []string) (column node, child *table, err error) {
|
||||
|
||||
// readRow pins the row a path reads of t: the one its selector names, or, where the
|
||||
// walk draws, one drawn where the path reads into the table.
|
||||
func readRow(d *hold, t *table, sel string, draw bool) error {
|
||||
func readRow(s *session, pins *pinSet, t *table, sel string, draw bool) error {
|
||||
if sel != "" {
|
||||
return d.selectRow(t, sel)
|
||||
return pins.selectRow(t, sel)
|
||||
}
|
||||
if draw && d.s != nil {
|
||||
d.rowOf(t)
|
||||
if draw && s != nil {
|
||||
pins.rowOf(s, t)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -312,8 +312,8 @@ func unreachableInChoice(c *choice, want string) error {
|
||||
// carries a repeat or a drawGroup, which one draw of it could not apply. So a path
|
||||
// that validates here resolves on every render, and a typo is a New-time error.
|
||||
func checkPath(n node, tail []string, level string) error {
|
||||
var pins hold
|
||||
_, err := walkPath(n, tail, pathWalk{
|
||||
var pins pinSet
|
||||
_, err := walkPath(nil, n, tail, pathWalk{
|
||||
choice: func(c *choice, rest []string) ([]node, error) {
|
||||
if err := carriedByAll(c, rest); err != nil {
|
||||
return nil, err
|
||||
|
||||
Reference in New Issue
Block a user