From c374e6c902165ac8c1258f3c2cdafdc70d7a46e8 Mon Sep 17 00:00:00 2001 From: Matthew Sackman Date: Thu, 17 Oct 2024 14:37:46 +0100 Subject: [PATCH] internal/core: add support for toposort to evalv2 Very similar to evalv3, we need to ensure the pointer to the parent declaration is populated in StructInfo. The same approach is taken, this time modifying closeInfo rather than closeContext, but there seem to be extra intermediate closeInfos sometimes added, so I need to inspect a closeInfo's ancestors to find the first non-nil declaration. Signed-off-by: Matthew Sackman Change-Id: I69cac611cd36c2376eaad785e1cc8bd24665c4c4 Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1202687 TryBot-Result: CUEcueckoo Unity-Result: CUE porcuepine Reviewed-by: Marcel van Lohuizen --- internal/core/adt/closed.go | 19 +++++++++++++++++++ internal/core/adt/composite.go | 2 ++ internal/core/adt/comprehension.go | 1 + internal/core/adt/eval.go | 1 + 4 files changed, 23 insertions(+) diff --git a/internal/core/adt/closed.go b/internal/core/adt/closed.go index b11fedbbb58..20b7db14618 100644 --- a/internal/core/adt/closed.go +++ b/internal/core/adt/closed.go @@ -180,6 +180,7 @@ func (c CloseInfo) SpawnEmbed(x Node) CloseInfo { mode: closeEmbed, root: EmbeddingSpan, span: c.span() | EmbeddingSpan, + decl: c.closeInfo.Decl(), } return c } @@ -193,6 +194,7 @@ func (c CloseInfo) SpawnGroup(x Expr) CloseInfo { parent: c.closeInfo, location: x, span: c.span(), + decl: c.closeInfo.Decl(), } return c } @@ -206,6 +208,7 @@ func (c CloseInfo) SpawnSpan(x Node, t SpanType) CloseInfo { location: x, root: t, span: c.span() | t, + decl: c.closeInfo.Decl(), } return c } @@ -228,6 +231,7 @@ func (c CloseInfo) SpawnRef(arc *Vertex, isDef bool, x Expr) CloseInfo { parent: c.closeInfo, location: x, span: span, + decl: c.closeInfo.Decl(), } } if isDef { @@ -294,6 +298,21 @@ type closeInfo struct { root SpanType span SpanType + + // decl is the parent declaration which contains the conjuct which + // gave rise to this closeInfo. + decl Decl +} + +// Returns the first non-nil Decl from c, or c's parents, if possible. +func (c *closeInfo) Decl() Decl { + for c != nil && c.decl == nil { + c = c.parent + } + if c == nil { + return nil + } + return c.decl } // closeStats holds the administrative fields for a closeInfo value. Each diff --git a/internal/core/adt/composite.go b/internal/core/adt/composite.go index 9514091aa2b..e9b6bf8a8c3 100644 --- a/internal/core/adt/composite.go +++ b/internal/core/adt/composite.go @@ -1399,6 +1399,8 @@ func (v *Vertex) AddStruct(s *StructLit, env *Environment, ci CloseInfo) *Struct } if cc := ci.cc; cc != nil && cc.decl != nil { info.Decl = cc.decl + } else if decl := ci.closeInfo.Decl(); decl != nil { + info.Decl = decl } for _, t := range v.Structs { if *t == info { // TODO: check for different identity. diff --git a/internal/core/adt/comprehension.go b/internal/core/adt/comprehension.go index 2a64b274023..86759d8467a 100644 --- a/internal/core/adt/comprehension.go +++ b/internal/core/adt/comprehension.go @@ -160,6 +160,7 @@ func (n *nodeContext) insertComprehension( if !n.ctx.isDevVersion() { ci = ci.SpawnEmbed(c) ci.closeInfo.span |= ComprehensionSpan + ci.decl = c } var decls []Decl diff --git a/internal/core/adt/eval.go b/internal/core/adt/eval.go index 84f06c898bc..37879f93c18 100644 --- a/internal/core/adt/eval.go +++ b/internal/core/adt/eval.go @@ -2153,6 +2153,7 @@ func (n *nodeContext) addStruct( // TODO(perf): only do this if addExprConjunct below will result in // a fieldSet. Otherwise the entry will just be removed next. id := closeInfo.SpawnEmbed(x) + id.decl = x c := MakeConjunct(childEnv, x, id) n.addExprConjunct(c, partial)