Skip to content

Commit

Permalink
Added basic snippet and fixed map and array completion bug, close #60
Browse files Browse the repository at this point in the history
  • Loading branch information
juliosueiras committed Apr 21, 2020
1 parent 2442e34 commit 9fd7728
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 80 deletions.
32 changes: 31 additions & 1 deletion hclstructs/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ func TemplateWrapExpr() reflect.Type {
return GetType(&hclsyntax.TemplateWrapExpr{})
}

func AnonSymbolExpr() reflect.Type {
return GetType(&hclsyntax.AnonSymbolExpr{})
}

func SplatExpr() reflect.Type {
return GetType(&hclsyntax.SplatExpr{})
}

// Traverse hcl
func TraverseAttr() reflect.Type {
return GetType(hcl.TraverseAttr{})
Expand Down Expand Up @@ -68,6 +76,10 @@ func GetExprStringType(origType reflect.Type) string {
return "string interpolation"
case ObjectConsExpr():
return "object"
case SplatExpr():
return "splat"
case AnonSymbolExpr():
return "anon symbol"
default:
return "undefined"
}
Expand Down Expand Up @@ -117,7 +129,12 @@ func GetExprVariables(origType reflect.Type, expr hcl.Expression, posHCL hcl.Pos
case TupleConsExpr():
expr := expr.(*hclsyntax.TupleConsExpr)
if expr.Range().ContainsPos(posHCL) {
return expr.Variables()
for _, newExpr := range expr.ExprList() {
if newExpr.Range().ContainsPos(posHCL) {
return newExpr.Variables()
}
}
return nil
}

// Need wrapped
Expand All @@ -127,6 +144,18 @@ func GetExprVariables(origType reflect.Type, expr hcl.Expression, posHCL hcl.Pos
return expr.Variables()
}

case AnonSymbolExpr():
expr := expr.(*hclsyntax.AnonSymbolExpr)
if expr.Range().ContainsPos(posHCL) || expr.SrcRange.ContainsPos(posHCL) {
return expr.Variables()
}

case SplatExpr():
expr := expr.(*hclsyntax.SplatExpr)
if expr.MarkerRange.ContainsPos(posHCL) || expr.Range().ContainsPos(posHCL) {
return expr.Source.Variables()
}

// Need more check
case ObjectConsExpr():
expr := expr.(*hclsyntax.ObjectConsExpr)
Expand All @@ -138,6 +167,7 @@ func GetExprVariables(origType reflect.Type, expr hcl.Expression, posHCL hcl.Pos
firstVar := hcl.TraverseAttr{
Name: v.KeyExpr.(*hclsyntax.ObjectConsKeyExpr).AsTraversal().RootName(),
}

vars := hcl.Traversal{
firstVar,
}
Expand Down
27 changes: 9 additions & 18 deletions helper/file.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package helper

import (
"github.com/davecgh/go-spew/spew"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclsyntax"
"github.com/hashicorp/terraform/configs"
"github.com/juliosueiras/terraform-lsp/hclstructs"
"github.com/juliosueiras/terraform-lsp/memfs"
log "github.com/sirupsen/logrus"
"github.com/sourcegraph/go-lsp"
"github.com/spf13/afero"
"github.com/zclconf/go-cty/cty"
Expand All @@ -23,12 +21,16 @@ func CheckAndGetConfig(parser *configs.Parser, originalFile afero.File, line int
pos := FindOffset(string(fileText), line, character)

tempFile, _ := afero.TempFile(memfs.MemFs, "", "check_tf_lsp")
found := false

defer memfs.MemFs.Remove(tempFile.Name())
if int64(pos) != -1 {
found = true
originalFile.ReadAt(result, int64(pos))
}

originalFile.ReadAt(result, int64(pos))
defer memfs.MemFs.Remove(tempFile.Name())

if string(result) == "." {
if found && string(result) == "." {
fileText[pos] = ' '

fileText = []byte(strings.Replace(string(fileText), ". ", " ", -1))
Expand All @@ -52,7 +54,6 @@ func CheckAndGetConfig(parser *configs.Parser, originalFile afero.File, line int
tempFile.Truncate(0)
tempFile.Seek(0, 0)
tempFile.Write([]byte(strings.Join(textLines, "\n")))
DumpLog(textLines)
resultConfig, diags := parser.LoadConfigFileOverride(tempFile.Name())
testRes, _ := parser.LoadHCLFile(tempFile.Name())
return resultConfig, diags, character, testRes.(*hclsyntax.Body), false
Expand All @@ -69,6 +70,7 @@ func FindOffset(fileText string, line, column int) int {
column = 1
}

//variable \"test\" {\n \n}\n\n
currentCol := 1
currentLine := 1

Expand All @@ -87,14 +89,6 @@ func FindOffset(fileText string, line, column int) int {
return -1
}

func DumpLog(res interface{}) {
result := spew.Sdump(res)
strSlice := strings.Split(result, "\n")
for _, s := range strSlice {
log.Debug(s)
}
}

func ParseVariables(vars hcl.Traversal, configVars map[string]*configs.Variable, completionItems []lsp.CompletionItem) []lsp.CompletionItem {
if len(vars) == 0 {
for _, t := range configVars {
Expand Down Expand Up @@ -130,6 +124,7 @@ func parseVariables(vars hcl.Traversal, configVarsType *cty.Type, completionItem
return completionItems
}


if !configVarsType.IsObjectType() {
if et := configVarsType.MapElementType(); et != nil {
return parseVariables(vars[1:], et, completionItems)
Expand All @@ -151,12 +146,8 @@ func parseVariables(vars hcl.Traversal, configVarsType *cty.Type, completionItem
return parseVariables(vars[1:], &attr, completionItems)
}
} else if reflect.TypeOf(vars[0]) == hclstructs.TraverseIndex() {
DumpLog(configVarsType)

return parseVariables(vars[1:], configVarsType, completionItems)
} else {
DumpLog(vars[0])
DumpLog(configVarsType)
}

return nil
Expand Down
43 changes: 21 additions & 22 deletions langserver/complete.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,19 +74,16 @@ func TextDocumentComplete(ctx context.Context, vs lsp.CompletionParams) (lsp.Com
}

if r, found, _ := tfstructs.GetTypeCompletion(result, fileDir, hclFile, posHCL, extraProvider); found {
helper.DumpLog("Found Type Completion")
return r, nil
}

config, origConfig, configType := tfstructs.GetConfig(file, posHCL)

if diags != nil || config == nil {
helper.DumpLog("With Error or No Config")
helper.DumpLog(diags)

return lsp.CompletionList{
IsIncomplete: false,
Items: tfstructs.GetTopLevelCompletion(),
Items: tfstructs.GetTopLevelCompletionWithPos(posHCL),
}, nil
}

Expand Down Expand Up @@ -139,10 +136,17 @@ func TextDocumentComplete(ctx context.Context, vs lsp.CompletionParams) (lsp.Com
params = append(params, x.Name)
}

var resultParams []string
for index, param := range params {
resultParams = append(resultParams, fmt.Sprintf("${%d:%s}", index+1, param))
}

result = append(result, lsp.CompletionItem{
Label: fmt.Sprintf("%s(%s)", k, strings.Join(params, ",")),
InsertText: k,
Detail: " function",
Label: fmt.Sprintf("%s(%s)", k, strings.Join(params, ",")),
Kind: lsp.CIKField,
InsertTextFormat: lsp.ITFSnippet,
InsertText: fmt.Sprintf("%s(%s)", k, strings.Join(resultParams, ",")),
Detail: " function",
})

}
Expand Down Expand Up @@ -173,7 +177,6 @@ func TextDocumentComplete(ctx context.Context, vs lsp.CompletionParams) (lsp.Com
}
}

//hclsyntax.LiteralValueExpr
if r, found, _ := tfstructs.GetAttributeCompletion(result, configType, origConfig, fileDir); found {
return r, nil
}
Expand All @@ -184,7 +187,6 @@ func TextDocumentComplete(ctx context.Context, vs lsp.CompletionParams) (lsp.Com
if blocks != nil && attr == nil {
//helper.DumpLog(blocks)
if blocks[0].Type == "provisioner" {
helper.DumpLog(blocks)
if len(blocks) == 1 {

if r, found, _ := tfstructs.GetAttributeCompletion(result, "provisioner", blocks[0], fileDir); found {
Expand Down Expand Up @@ -220,10 +222,11 @@ func TextDocumentComplete(ctx context.Context, vs lsp.CompletionParams) (lsp.Com
}
}

if expr == nil {
expr = attr.Expr
}

if expr != nil {
helper.DumpLog("Found Expression")
helper.DumpLog(posHCL)
helper.DumpLog(expr)
//.*for.*in\s+([^:]*)
//te, te2 := hclsyntax.ParseExpression([]byte("aws[0].test"), "test", hcl.Pos{
// Line: 0,
Expand All @@ -241,7 +244,6 @@ func TextDocumentComplete(ctx context.Context, vs lsp.CompletionParams) (lsp.Com
searchResult := re.FindSubmatch([]byte(textLines[vs.Position.Line]))

if searchResult != nil {
helper.DumpLog(searchResult[1])
dynamicExpr, _ := hclsyntax.ParseExpression([]byte(searchResult[1]), "test", hcl.Pos{
Line: 0,
Column: 0,
Expand All @@ -266,9 +268,7 @@ func TextDocumentComplete(ctx context.Context, vs lsp.CompletionParams) (lsp.Com
//reflect.New(origType)
if origType == hclstructs.ForExpr() {
expr := expr.(*hclsyntax.ForExpr)
helper.DumpLog(expr)
resultName := []string{}
helper.DumpLog(expr.ValExpr.Range().ContainsPos(posHCL))
if expr.ValExpr.Range().ContainsPos(posHCL) {
if reflect.TypeOf(expr.CollExpr) == hclstructs.ScopeTraversalExpr() {
resultName = append(resultName, expr.CollExpr.(*hclsyntax.ScopeTraversalExpr).AsTraversal().RootName())
Expand All @@ -283,10 +283,7 @@ func TextDocumentComplete(ctx context.Context, vs lsp.CompletionParams) (lsp.Com
}

scopeExpr := expr.ValExpr.(*hclsyntax.ScopeTraversalExpr)
helper.DumpLog(haveDot)
helper.DumpLog((len(scopeExpr.AsTraversal()) == 1 && haveDot) || len(scopeExpr.AsTraversal()) > 1)
if len(scopeExpr.AsTraversal()) == 1 && !haveDot {
helper.DumpLog(vs.Position.Character)
result = append(result, lsp.CompletionItem{
Label: expr.ValVar,
Detail: fmt.Sprintf(" foreach var(%s)", strings.Join(resultName, ".")),
Expand Down Expand Up @@ -317,10 +314,12 @@ func TextDocumentComplete(ctx context.Context, vs lsp.CompletionParams) (lsp.Com
}
}
//tests, errxs := lang.ReferencesInExpr(expr)
if origType != hclstructs.ObjectConsExpr() {
variables := hclstructs.GetExprVariables(origType, expr, posHCL)

if len(variables) != 0 {
variables := hclstructs.GetExprVariables(origType, expr, posHCL)

if len(variables) == 1 || variables == nil {

if variables != nil && len(variables) != 0 {
result = tfstructs.GetVarAttributeCompletion(tfstructs.GetVarAttributeRequest{
Variables: variables[0],
Result: result,
Expand Down Expand Up @@ -390,7 +389,7 @@ func TextDocumentComplete(ctx context.Context, vs lsp.CompletionParams) (lsp.Com
}
} else {
if blocks == nil && attr != nil {
if r, found, _ := tfstructs.GetNestingAttributeCompletion(attr, result, configType, origConfig, fileDir, posHCL); found {
if r, found, _ := tfstructs.GetNestingAttributeCompletion(attr, result, configType, origConfig, fileDir, posHCL, origType); found {
return r, nil
}
}
Expand Down
15 changes: 15 additions & 0 deletions loghelper/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package loghelper

import (
"github.com/davecgh/go-spew/spew"
log "github.com/sirupsen/logrus"
"strings"
)

func DumpLog(res interface{}) {
result := spew.Sdump(res)
strSlice := strings.Split(result, "\n")
for _, s := range strSlice {
log.Debug(s)
}
}
6 changes: 5 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ func init() {
}

func main() {

oldLog.SetOutput(ioutil.Discard)
oldLog.SetFlags(0)

Expand All @@ -51,6 +50,11 @@ func main() {

debug := viper.GetBool("debug")
log.Infof("Log Level is Debug: %t", debug)
log.SetFormatter(&log.TextFormatter{
DisableTimestamp: true,
ForceColors: true,
DisableLevelTruncation: true,
})

if debug {
log.SetLevel(log.DebugLevel)
Expand Down
Loading

0 comments on commit 9fd7728

Please sign in to comment.