From 8d100bfde9bafa9b2fa42aaa417e3b91031a851b Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Wed, 17 Oct 2018 17:47:13 -0700 Subject: [PATCH] tfdiags: Expose expression evaluation information from diagnostics HCL diagnostics relating to expression evaluation include these, so this is really just to pass that information through our Terraform-specific diagnostics interface. --- tfdiags/diagnostic.go | 14 ++++++++++++++ tfdiags/diagnostic_base.go | 10 +++++++--- tfdiags/error.go | 5 +++++ tfdiags/hcl.go | 10 ++++++++++ tfdiags/rpc_friendly.go | 6 ++++++ tfdiags/simple_warning.go | 7 ++++++- 6 files changed, 48 insertions(+), 4 deletions(-) diff --git a/tfdiags/diagnostic.go b/tfdiags/diagnostic.go index 2c23f76ae5..c91ba9a529 100644 --- a/tfdiags/diagnostic.go +++ b/tfdiags/diagnostic.go @@ -1,9 +1,18 @@ package tfdiags +import ( + "github.com/hashicorp/hcl2/hcl" +) + type Diagnostic interface { Severity() Severity Description() Description Source() Source + + // FromExpr returns the expression-related context for the diagnostic, if + // available. Returns nil if the diagnostic is not related to an + // expression evaluation. + FromExpr() *FromExpr } type Severity rune @@ -24,3 +33,8 @@ type Source struct { Subject *SourceRange Context *SourceRange } + +type FromExpr struct { + Expression hcl.Expression + EvalContext *hcl.EvalContext +} diff --git a/tfdiags/diagnostic_base.go b/tfdiags/diagnostic_base.go index 6de82ee82f..50bf9d8eba 100644 --- a/tfdiags/diagnostic_base.go +++ b/tfdiags/diagnostic_base.go @@ -2,9 +2,9 @@ package tfdiags // diagnosticBase can be embedded in other diagnostic structs to get // default implementations of Severity and Description. This type also -// has a default implementation of Source that returns no source location -// information, so embedders should generally override that method to -// return more useful results. +// has default implementations of Source and FromExpr that return no source +// location or expression-related information, so embedders should generally +// override those method to return more useful results where possible. type diagnosticBase struct { severity Severity summary string @@ -25,3 +25,7 @@ func (d diagnosticBase) Description() Description { func (d diagnosticBase) Source() Source { return Source{} } + +func (d diagnosticBase) FromExpr() *FromExpr { + return nil +} diff --git a/tfdiags/error.go b/tfdiags/error.go index 4ad6b0567d..13f7a714f4 100644 --- a/tfdiags/error.go +++ b/tfdiags/error.go @@ -21,3 +21,8 @@ func (e nativeError) Source() Source { // No source information available for a native error return Source{} } + +func (e nativeError) FromExpr() *FromExpr { + // Native errors are not expression-related + return nil +} diff --git a/tfdiags/hcl.go b/tfdiags/hcl.go index 24851f4d00..f9aec41c93 100644 --- a/tfdiags/hcl.go +++ b/tfdiags/hcl.go @@ -40,6 +40,16 @@ func (d hclDiagnostic) Source() Source { return ret } +func (d hclDiagnostic) FromExpr() *FromExpr { + if d.diag.Expression == nil || d.diag.EvalContext == nil { + return nil + } + return &FromExpr{ + Expression: d.diag.Expression, + EvalContext: d.diag.EvalContext, + } +} + // SourceRangeFromHCL constructs a SourceRange from the corresponding range // type within the HCL package. func SourceRangeFromHCL(hclRange hcl.Range) SourceRange { diff --git a/tfdiags/rpc_friendly.go b/tfdiags/rpc_friendly.go index 6cc95cc2ed..485063b0c0 100644 --- a/tfdiags/rpc_friendly.go +++ b/tfdiags/rpc_friendly.go @@ -48,6 +48,12 @@ func (d *rpcFriendlyDiag) Source() Source { } } +func (d rpcFriendlyDiag) FromExpr() *FromExpr { + // RPC-friendly diagnostics cannot preserve expression information because + // expressions themselves are not RPC-friendly. + return nil +} + func init() { gob.Register((*rpcFriendlyDiag)(nil)) } diff --git a/tfdiags/simple_warning.go b/tfdiags/simple_warning.go index fb3ac98989..b0f1ecd46c 100644 --- a/tfdiags/simple_warning.go +++ b/tfdiags/simple_warning.go @@ -20,6 +20,11 @@ func (e simpleWarning) Description() Description { } func (e simpleWarning) Source() Source { - // No source information available for a native error + // No source information available for a simple warning return Source{} } + +func (e simpleWarning) FromExpr() *FromExpr { + // Simple warnings are not expression-related + return nil +}