mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
lang: Split enhanceFunctionDiags loop body into separate function
This function was previously failing the nestif lint rule. Factoring the loop body out into a separate function avoids that problem and also subjectively makes this easier to follow by separating the functional-style enhanceFunctionDiag from the mutation of the backing array of the caller's diags slice. This also transforms enhanceFunctionDiags into a package-level function rather than a method of Scope, since in practice it doesn't actually use anything from Scope. Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
This commit is contained in:
parent
972324e5ea
commit
45131c4c0c
@ -75,7 +75,7 @@ func (s *Scope) EvalBlock(body hcl.Body, schema *configschema.Block) (cty.Value,
|
||||
body = blocktoattr.FixUpBlockAttrs(body, schema)
|
||||
|
||||
val, evalDiags := hcldec.Decode(body, spec, ctx)
|
||||
diags = diags.Append(s.enhanceFunctionDiags(evalDiags))
|
||||
diags = diags.Append(enhanceFunctionDiags(evalDiags))
|
||||
|
||||
return val, diags
|
||||
}
|
||||
@ -155,7 +155,7 @@ func (s *Scope) EvalSelfBlock(body hcl.Body, self cty.Value, schema *configschem
|
||||
}
|
||||
|
||||
val, decDiags := hcldec.Decode(body, schema.DecoderSpec(), ctx)
|
||||
diags = diags.Append(s.enhanceFunctionDiags(decDiags))
|
||||
diags = diags.Append(enhanceFunctionDiags(decDiags))
|
||||
return val, diags
|
||||
}
|
||||
|
||||
@ -181,7 +181,7 @@ func (s *Scope) EvalExpr(expr hcl.Expression, wantType cty.Type) (cty.Value, tfd
|
||||
}
|
||||
|
||||
val, evalDiags := expr.Value(ctx)
|
||||
diags = diags.Append(s.enhanceFunctionDiags(evalDiags))
|
||||
diags = diags.Append(enhanceFunctionDiags(evalDiags))
|
||||
|
||||
if wantType != cty.DynamicPseudoType {
|
||||
var convErr error
|
||||
@ -203,49 +203,57 @@ func (s *Scope) EvalExpr(expr hcl.Expression, wantType cty.Type) (cty.Value, tfd
|
||||
}
|
||||
|
||||
// Identify and enhance any function related dialogs produced by a hcl.EvalContext
|
||||
func (s *Scope) enhanceFunctionDiags(diags hcl.Diagnostics) hcl.Diagnostics {
|
||||
func enhanceFunctionDiags(diags hcl.Diagnostics) hcl.Diagnostics {
|
||||
out := make(hcl.Diagnostics, len(diags))
|
||||
for i, diag := range diags {
|
||||
out[i] = diag
|
||||
|
||||
if funcExtra, ok := diag.Extra.(hclsyntax.FunctionCallUnknownDiagExtra); ok {
|
||||
funcName := funcExtra.CalledFunctionName()
|
||||
// prefix::stuff::
|
||||
fullNamespace := funcExtra.CalledFunctionNamespace()
|
||||
|
||||
if len(fullNamespace) == 0 {
|
||||
// Not a namespaced function, no enhancements necessary
|
||||
continue
|
||||
}
|
||||
|
||||
// Insert the enhanced copy of diag into diags
|
||||
enhanced := *diag
|
||||
out[i] = &enhanced
|
||||
|
||||
// Update enhanced with additional details
|
||||
|
||||
fn := addrs.ParseFunction(fullNamespace + funcName)
|
||||
|
||||
if fn.IsNamespace(addrs.FunctionNamespaceCore) {
|
||||
// Error is in core namespace, mirror non-core equivalent
|
||||
enhanced.Summary = "Call to unknown function"
|
||||
enhanced.Detail = fmt.Sprintf("There is no builtin (%s::) function named %q.", addrs.FunctionNamespaceCore, funcName)
|
||||
} else if fn.IsNamespace(addrs.FunctionNamespaceProvider) {
|
||||
if _, err := fn.AsProviderFunction(); err != nil {
|
||||
// complete mismatch or invalid prefix
|
||||
enhanced.Summary = "Invalid function format"
|
||||
enhanced.Detail = err.Error()
|
||||
}
|
||||
} else {
|
||||
enhanced.Summary = "Unknown function namespace"
|
||||
enhanced.Detail = fmt.Sprintf("Function %q does not exist within a valid namespace (%s)", fn, strings.Join(addrs.FunctionNamespaces, ","))
|
||||
}
|
||||
// Function / Provider not found handled by eval_context_builtin.go
|
||||
out[i] = enhanceFunctionDiag(diag, funcExtra)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// enhanceFunctionDiag returns a potentially-improved version of the given diagnostic
|
||||
// based on the information in funcExtra.
|
||||
func enhanceFunctionDiag(diag *hcl.Diagnostic, funcExtra hclsyntax.FunctionCallUnknownDiagExtra) *hcl.Diagnostic {
|
||||
funcName := funcExtra.CalledFunctionName()
|
||||
// prefix::stuff::
|
||||
fullNamespace := funcExtra.CalledFunctionNamespace()
|
||||
|
||||
if len(fullNamespace) == 0 {
|
||||
// Not a namespaced function, no enhancements necessary
|
||||
return diag
|
||||
}
|
||||
|
||||
// Shallow copy of the given diagnostic so that we can modify it without affecting
|
||||
// anyone else that might be holding a pointer to it.
|
||||
enhanced := *diag
|
||||
|
||||
// Update enhanced with additional details
|
||||
|
||||
fn := addrs.ParseFunction(fullNamespace + funcName)
|
||||
|
||||
if fn.IsNamespace(addrs.FunctionNamespaceCore) {
|
||||
// Error is in core namespace, mirror non-core equivalent
|
||||
enhanced.Summary = "Call to unknown function"
|
||||
enhanced.Detail = fmt.Sprintf("There is no builtin (%s::) function named %q.", addrs.FunctionNamespaceCore, funcName)
|
||||
} else if fn.IsNamespace(addrs.FunctionNamespaceProvider) {
|
||||
if _, err := fn.AsProviderFunction(); err != nil {
|
||||
// complete mismatch or invalid prefix
|
||||
enhanced.Summary = "Invalid function format"
|
||||
enhanced.Detail = err.Error()
|
||||
}
|
||||
} else {
|
||||
enhanced.Summary = "Unknown function namespace"
|
||||
enhanced.Detail = fmt.Sprintf("Function %q does not exist within a valid namespace (%s)", fn, strings.Join(addrs.FunctionNamespaces, ","))
|
||||
}
|
||||
// Function / Provider not found handled by eval_context_builtin.go
|
||||
|
||||
return &enhanced
|
||||
}
|
||||
|
||||
// EvalReference evaluates the given reference in the receiving scope and
|
||||
// returns the resulting value. The value will be converted to the given type before
|
||||
// it is returned if possible, or else an error diagnostic will be produced
|
||||
|
@ -798,7 +798,6 @@ func TestScopeExpandEvalBlock(t *testing.T) {
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func formattedJSONValue(val cty.Value) string {
|
||||
@ -1008,7 +1007,7 @@ func Test_enhanceFunctionDiags(t *testing.T) {
|
||||
}
|
||||
|
||||
_, evalDiags := hcldec.Decode(body, spec, ctx)
|
||||
diags := scope.enhanceFunctionDiags(evalDiags)
|
||||
diags := enhanceFunctionDiags(evalDiags)
|
||||
if len(diags) != 1 {
|
||||
t.Fatalf("Expected 1 diag, got %d", len(diags))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user