diff --git a/dag/new.txt b/dag/new.txt new file mode 100644 index 000000000000..60cb268d4849 --- /dev/null +++ b/dag/new.txt @@ -0,0 +1,6 @@ +goos: darwin +goarch: amd64 +pkg: github.com/hashicorp/terraform/dag +BenchmarkDAG-4 2 11022154016 ns/op 2049244080 B/op 61428144 allocs/op +PASS +ok github.com/hashicorp/terraform/dag 35.729s diff --git a/dag/old.txt b/dag/old.txt new file mode 100644 index 000000000000..d9441ccde2b2 --- /dev/null +++ b/dag/old.txt @@ -0,0 +1,6 @@ +goos: darwin +goarch: amd64 +pkg: github.com/hashicorp/terraform/dag +BenchmarkDAG-4 1 66577406455 ns/op 5917501632 B/op 576835287 allocs/op +PASS +ok github.com/hashicorp/terraform/dag 68.575s diff --git a/diagsvet b/diagsvet new file mode 100755 index 000000000000..b659c583ec7b Binary files /dev/null and b/diagsvet differ diff --git a/diagsvet.go b/diagsvet.go new file mode 100644 index 000000000000..c8933476ddb4 --- /dev/null +++ b/diagsvet.go @@ -0,0 +1,74 @@ +// +build ignore + +package main + +import ( + "fmt" + "go/ast" + "go/token" + "go/types" + "strings" + + "github.com/hashicorp/terraform/tfdiags" + "golang.org/x/tools/go/analysis" + "golang.org/x/tools/go/analysis/passes/inspect" + "golang.org/x/tools/go/analysis/unitchecker" + "golang.org/x/tools/go/ast/inspector" +) + +var Analyzer = &analysis.Analyzer{ + Name: "diags", + Doc: "check for diagnostic assignments to error variables", + Requires: []*analysis.Analyzer{inspect.Analyzer}, + Run: run, +} + +func run(pass *analysis.Pass) (interface{}, error) { + inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) + + nodeFilter := []ast.Node{ + (*ast.AssignStmt)(nil), + } + inspect.Preorder(nodeFilter, func(n ast.Node) { + stmt := n.(*ast.AssignStmt) + if stmt.Tok != token.DEFINE { + return // ignore = + } + + err := tfdiags.Diagnostics{} + if err != nil { + } + + for _, x := range stmt.Lhs { + id, isId := x.(*ast.Ident) + if !isId { + continue + } + + // any e, err, myErr, etc + if !(id.Name == "e" || strings.Contains(id.Name, "err") || strings.Contains(id.Name, "Err")) { + continue + } + + def := pass.TypesInfo.Defs[id] + if def == nil { + continue + } + named, ok := def.Type().(*types.Named) + if !ok { + continue + } + typeName := named.Obj().Name() + + if strings.HasPrefix(typeName, "Diagnostic") { + pass.Reportf(stmt.Pos(), fmt.Sprintf("%s type assigned to variable named %q", typeName, id.Name)) + } + } + }) + + return nil, nil +} + +func main() { + unitchecker.Main(Analyzer) +} diff --git a/terraform/node_resource_destroy.go b/terraform/node_resource_destroy.go index c5042436dde4..4e495cbcb900 100644 --- a/terraform/node_resource_destroy.go +++ b/terraform/node_resource_destroy.go @@ -282,12 +282,28 @@ type NodeDestroyResource struct { var ( _ GraphNodeEvalable = (*NodeDestroyResource)(nil) + // TransformReferences looks for indirect references as well, and relies + // on these two interfaces to connect them. + _ GraphNodeReferenceable = (*NodeDestroyResource)(nil) + _ GraphNodeSubPath = (*NodeDestroyResource)(nil) ) func (n *NodeDestroyResource) Name() string { return n.NodeAbstractResource.ResourceAddr().String() + " (clean up state)" } +// NodeDestroyResource still needs to be a GraphNodeReferenceable so that a +// NodeModuleRemoved can reference it for cleanup. +func (n *NodeDestroyResource) ReferenceableAddrs() []addrs.Referenceable { + return n.NodeAbstractResource.ReferenceableAddrs() +} + +// NodeDestroyResource still needs to be a GraphNodeSubPath so that a +// NodeModuleRemoved can reference it for cleanup. +func (n *NodeDestroyResource) Path() addrs.ModuleInstance { + return n.NodeAbstractResource.Path() +} + // GraphNodeEvalable func (n *NodeDestroyResource) EvalTree() EvalNode { // This EvalNode will produce an error if the resource isn't already