Files
gof3/tree/generic/references.go
2024-01-20 11:25:22 +00:00

59 lines
1.7 KiB
Go

// Copyright Earl Warren <contact@earl-warren.org>
// Copyright Loïc Dachary <loic@dachary.org>
// SPDX-License-Identifier: MIT
package generic
import (
"context"
"lab.forgefriends.org/friendlyforgeformat/gof3/util"
)
func NodeCollectReferences(ctx context.Context, node NodeInterface) []Path {
pathToReferences := make(map[string]Path, 5)
tree := node.GetTree()
collect := func(ctx context.Context, parent Path, node NodeInterface) {
util.MaybeTerminate(ctx)
f := node.GetSelf().ToFormat()
for _, reference := range f.GetReferences() {
absoluteReference := PathAbsoluteString(node.GetCurrentPath().String(), reference.Get())
if _, ok := pathToReferences[absoluteReference]; ok {
continue
}
found := tree.ApplyAndGet(ctx, NewPathFromString(absoluteReference), NewApplyOptions(func(ctx context.Context, parent, path Path, node NodeInterface) {
if !node.GetIsSync() {
node.Get(ctx)
}
pathToReferences[absoluteReference] = node.GetCurrentPath()
}))
if !found {
panic(NewError[ErrorNodeNotFound]("reference %s is not found in %s", reference.Get(), node.GetCurrentPath()))
}
}
}
node.Walk(ctx, NewPath(node), NewWalkOptions(collect))
references := make([]Path, 0, len(pathToReferences))
for _, reference := range pathToReferences {
tree.Debug("collect %s", reference)
references = append(references, reference)
}
return references
}
func TreeCollectReferences(ctx context.Context, tree TreeInterface, path Path) []Path {
var references []Path
tree.Apply(ctx, path, NewApplyOptions(func(ctx context.Context, parent, path Path, node NodeInterface) {
references = NodeCollectReferences(ctx, node)
}))
return references
}