mirror of
https://github.com/opentffoundation/opentf.git
synced 2025-12-21 10:47:34 -05:00
In "package tofu" today we try to do everything using a generic acyclic graph model and generic graph walk, which _works_ but tends to make every other part of the problem very hard to follow because we rely a lot on sidecar shared mutable data structures to propagate results between the isolated operations. This is the beginning of an experimental new way to do it where the "graph" is implied by a model that more closely represents how the language itself works, with explicit modelling of the relationships between different types of objects and letting results flow directly from one object to another without any big shared mutable state. There's still a lot to do before this is actually complete enough to evaluate whether it's a viable new design, but I'm considering this a good starting checkpoint since there's enough here to run a simple test of propagating data all the way from input variables to output values via intermediate local values. Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
49 lines
1.6 KiB
Go
49 lines
1.6 KiB
Go
// Copyright (c) The OpenTofu Authors
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
// Copyright (c) 2023 HashiCorp, Inc.
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package exprs
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/hashicorp/hcl/v2"
|
|
"github.com/opentofu/opentofu/internal/tfdiags"
|
|
"github.com/zclconf/go-cty/cty/function"
|
|
)
|
|
|
|
// Scope is implemented by types representing containers that can have
|
|
// expressions evaluated within them.
|
|
//
|
|
// For example, it might make sense for a type representing a module instance
|
|
// to implement this interface to describe the symbols and functions that
|
|
// result from the declarations in that module instance. In that case, the
|
|
// module instance _is_ the scope, rather than the scope being a separate thing
|
|
// derived from that module instance.
|
|
//
|
|
// A Scope is essentially just an extension of [SymbolTable] which also includes
|
|
// a table of functions.
|
|
type Scope interface {
|
|
SymbolTable
|
|
|
|
// ResolveFunc looks up a function by name, either returning its
|
|
// implementation or error diagnostics if no such function exists.
|
|
ResolveFunc(call *hcl.StaticCall) (function.Function, tfdiags.Diagnostics)
|
|
}
|
|
|
|
// ChildScopeBuilder is the signature for a function that can build a child
|
|
// scope that wraps some given parent scope.
|
|
//
|
|
// A nil [ChildScopeBuilder] represents that no child scope is needed and the
|
|
// parent should just be used directly. Use [ChildScopeBuilder.Build] instead
|
|
// of directly calling the function to obtain that behavior automatically.
|
|
type ChildScopeBuilder func(ctx context.Context, parent Scope) Scope
|
|
|
|
func (b ChildScopeBuilder) Build(ctx context.Context, parent Scope) Scope {
|
|
if b == nil {
|
|
return parent
|
|
}
|
|
return b(ctx, parent)
|
|
}
|