diff --git a/internal/core/adt/debug.go b/internal/core/adt/debug.go index f07b6848665..22630663528 100644 --- a/internal/core/adt/debug.go +++ b/internal/core/adt/debug.go @@ -622,6 +622,8 @@ func (m *mermaidContext) pstr(cc *closeContext) string { addFlag(cc.isDef, '#') addFlag(cc.isEmbed, 'E') addFlag(cc.isClosed, 'c') + addFlag(cc.isClosedOnce, 'C') + addFlag(cc.hasEllipsis, 'o') io.Copy(w, flags) w.WriteString(close) diff --git a/internal/core/adt/fields.go b/internal/core/adt/fields.go index 70ccda1ce63..fd4f54f1ddb 100644 --- a/internal/core/adt/fields.go +++ b/internal/core/adt/fields.go @@ -180,6 +180,19 @@ type closeContext struct { // definition. isDef bool + // hasEllipsis indicates whether the node contains an ellipsis. + hasEllipsis bool + + // hasTop indicates a node has at least one top conjunct. + hasTop bool + + // hasNonTop indicates a node has at least one conjunct that is not top. + hasNonTop bool + + // isClosedOnce is true if this closeContext is the result of calling the + // close builtin. + isClosedOnce bool + // isEmbed indicates whether the closeContext is created as part of an // embedding. isEmbed bool @@ -415,6 +428,13 @@ func (c *closeContext) addDependency(kind depKind, key, child *closeContext) { panic("addArc: Label already exists") } } + + // TODO: this tests seems sensible, but panics. Investigate what could + // trigger this. + // if child.src.Parent != c.src { + // panic("addArc: inconsistent parent") + // } + c.arcs = append(c.arcs, ccArc{kind: kind, key: key, cc: child}) } @@ -460,13 +480,20 @@ func (c *closeContext) decDependent(ctx *OpContext, kind depKind, dependant *clo p := c.parent - if c.isDef { + if c.isDef && !c.hasEllipsis && (!c.hasTop || c.hasNonTop) { c.isClosed = true if p != nil { p.isDef = true } } + if c.isClosedOnce { + c.isClosed = true + if p != nil { + p.isClosedOnce = true + } + } + for _, a := range c.arcs { cc := a.cc cc.decDependent(ctx, a.kind, c) // REF(arcs) @@ -486,6 +513,16 @@ func (c *closeContext) decDependent(ctx *OpContext, kind depKind, dependant *clo return } + if c.hasEllipsis { + p.hasEllipsis = true + } + if c.hasTop { + p.hasTop = true + } + if c.hasNonTop { + p.hasNonTop = true + } + if !c.isEmbed && c.isClosed { // Merge the two closeContexts and ensure that the patterns and fields // are mutually compatible according to the closedness rules.