From 8c4728ad3c9f108538ba266baaea1616a7896337 Mon Sep 17 00:00:00 2001 From: Julio Tain Sueiras Date: Fri, 5 Jul 2019 22:09:22 -0400 Subject: [PATCH] Added local vars completion --- hclstructs/main.go | 27 +++++++++++++++++++ tfstructs/main.go | 1 + tfstructs/vars.go | 65 ++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 91 insertions(+), 2 deletions(-) diff --git a/hclstructs/main.go b/hclstructs/main.go index a83cbbd..db00d35 100644 --- a/hclstructs/main.go +++ b/hclstructs/main.go @@ -48,6 +48,33 @@ func TraverseIndex() reflect.Type { return GetType(hcl.TraverseIndex{}) } +func GetExprStringType(origType reflect.Type) string { + + switch origType { + // May need recursion + case BinaryOpExpr(): + return "binary operation" + case FunctionCallExpr(): + return "function call" + case ScopeTraversalExpr(): + return "scoped expression" + case LiteralValueExpr(): + return "literal value" + case ForExpr(): + return "for loop" + case TupleConsExpr(): + return "array" + case TemplateWrapExpr(): + return "string interpolation" + case ObjectConsExpr(): + return "object" + default: + return "undefined" + } + + return "undefined" +} + func GetExprVariables(origType reflect.Type, expr hcl.Expression, posHCL hcl.Pos) []hcl.Traversal { switch origType { diff --git a/tfstructs/main.go b/tfstructs/main.go index d91b330..601efec 100644 --- a/tfstructs/main.go +++ b/tfstructs/main.go @@ -105,6 +105,7 @@ func GetDataSourceSchema(dataSourceType string, config hcl.Body, targetDir strin "data": cty.DynamicVal, "var": cty.DynamicVal, // Need to check for undefined vars "module": cty.DynamicVal, + "local": cty.DynamicVal, }, Functions: scope.Functions(), }) diff --git a/tfstructs/vars.go b/tfstructs/vars.go index 5edeb33..8cbd9a1 100644 --- a/tfstructs/vars.go +++ b/tfstructs/vars.go @@ -1,11 +1,15 @@ package tfstructs import ( + "fmt" "github.com/hashicorp/hcl2/hcl" + "github.com/hashicorp/hcl2/hcl/hclsyntax" "github.com/hashicorp/terraform/addrs" "github.com/hashicorp/terraform/configs" + "github.com/juliosueiras/terraform-lsp/hclstructs" "github.com/juliosueiras/terraform-lsp/helper" "github.com/sourcegraph/go-lsp" + "reflect" ) type GetVarAttributeRequest struct { @@ -17,12 +21,69 @@ type GetVarAttributeRequest struct { } func GetVarAttributeCompletion(request GetVarAttributeRequest) []lsp.CompletionItem { - helper.DumpLog("hi") - helper.DumpLog(request.Variables) if request.Variables.RootName() == "var" { vars := request.Variables request.Result = helper.ParseVariables(vars[1:], request.Files.Variables, request.Result) + } else if request.Variables.RootName() == "local" { + if len(request.Variables) > 1 { + var found *configs.Local + for _, v := range request.Files.Locals { + if v.Name == request.Variables[1].(hcl.TraverseAttr).Name { + found = v + break + } + } + + origType := reflect.TypeOf(found.Expr) + + if origType == hclstructs.ObjectConsExpr() { + items := found.Expr.(*hclsyntax.ObjectConsExpr).Items + for _, v := range request.Variables[2:] { + for _, l := range items { + if v.(hcl.TraverseAttr).Name == l.KeyExpr.(*hclsyntax.ObjectConsKeyExpr).Wrapped.(*hclsyntax.ScopeTraversalExpr).AsTraversal().RootName() { + origType2 := reflect.TypeOf(l.ValueExpr) + + if origType2 == hclstructs.ObjectConsExpr() { + items = l.ValueExpr.(*hclsyntax.ObjectConsExpr).Items + } + } + } + } + + for _, v := range items { + origType2 := reflect.TypeOf(v.ValueExpr) + helper.DumpLog(v.KeyExpr.(*hclsyntax.ObjectConsKeyExpr).Wrapped.(*hclsyntax.ScopeTraversalExpr).AsTraversal().RootName()) + request.Result = append(request.Result, lsp.CompletionItem{ + Label: v.KeyExpr.(*hclsyntax.ObjectConsKeyExpr).Wrapped.(*hclsyntax.ScopeTraversalExpr).AsTraversal().RootName(), + Detail: fmt.Sprintf(" %s", hclstructs.GetExprStringType(origType2)), + }) + } + } + + return request.Result + + } else if len(request.Variables) == 1 { + for _, v := range request.Files.Locals { + origType := reflect.TypeOf(v.Expr) + request.Result = append(request.Result, lsp.CompletionItem{ + Label: v.Name, + Detail: fmt.Sprintf(" local value(%s)", hclstructs.GetExprStringType(origType)), + }) + } + + return request.Result + } else { + for _, v := range request.Files.Locals { + origType := reflect.TypeOf(v.Expr) + request.Result = append(request.Result, lsp.CompletionItem{ + Label: v.Name, + Detail: fmt.Sprintf(" local value(%s)", hclstructs.GetExprStringType(origType)), + }) + } + + return request.Result + } } else if request.Variables.RootName() == "data" { // Need refactoring if len(request.Variables) > 2 {