Skip to content

Commit

Permalink
LiteralValue completion, hover and semantic tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
jpogran committed Mar 30, 2023
1 parent 90a4850 commit b8f42e4
Show file tree
Hide file tree
Showing 8 changed files with 4,009 additions and 59 deletions.
27 changes: 16 additions & 11 deletions decoder/expr_literal_value.go
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
package decoder

import (
"context"
"fmt"
"strconv"

"github.com/hashicorp/hcl-lang/lang"
"github.com/hashicorp/hcl-lang/schema"
"github.com/hashicorp/hcl/v2"
"github.com/zclconf/go-cty/cty"
)

type LiteralValue struct {
expr hcl.Expression
cons schema.LiteralValue
expr hcl.Expression
cons schema.LiteralValue
pathCtx *PathContext
}

func (lv LiteralValue) HoverAtPos(ctx context.Context, pos hcl.Pos) *lang.HoverData {
// TODO
return nil
}
func formatNumberVal(val cty.Value) string {
bf := val.AsBigFloat()

if bf.IsInt() {
intNum, _ := bf.Int64()
return fmt.Sprintf("%d", intNum)
}

fNum, _ := bf.Float64()
return strconv.FormatFloat(fNum, 'f', -1, 64)

func (lv LiteralValue) SemanticTokens(ctx context.Context) []lang.SemanticToken {
// TODO
return nil
}
102 changes: 69 additions & 33 deletions decoder/expr_literal_value_completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import (
"context"

"github.com/hashicorp/hcl-lang/lang"
"github.com/hashicorp/hcl-lang/schema"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclsyntax"
"github.com/zclconf/go-cty/cty"
)

Expand All @@ -18,45 +20,79 @@ func (lv LiteralValue) CompletionAtPos(ctx context.Context, pos hcl.Pos) []lang.
End: pos,
}

if typ.IsPrimitiveType() {
if typ == cty.Bool {
label := "false"
if lv.cons.Value.True() {
label = "true"
}

return []lang.Candidate{
{
Label: label,
Detail: typ.FriendlyName(),
Kind: lang.BoolCandidateKind,
TextEdit: lang.TextEdit{
NewText: label,
Snippet: label,
Range: editRange,
},
},
}
}
return []lang.Candidate{}
}
// We expect values to be always fully populated
ctx = schema.WithPrefillRequiredFields(ctx, true)

if typ == cty.DynamicPseudoType {
return []lang.Candidate{}
}
cd := lv.cons.EmptyCompletionData(ctx, 1, 0)

return []lang.Candidate{}
return []lang.Candidate{
{
Label: labelForLiteralValue(lv.cons.Value, false),
Detail: typ.FriendlyName(),
Kind: candidateKindForType(typ),
TextEdit: lang.TextEdit{
Range: editRange,
NewText: cd.NewText,
Snippet: cd.Snippet,
},
TriggerSuggest: cd.TriggerSuggest,
},
}
}

if typ == cty.Bool {
return []lang.Candidate{}
return lv.completeBoolAtPos(ctx, pos)
}

// TODO: delegate cty.Map to Map
// TODO: delegate cty.Object to Object
// TODO: delegate cty.Tuple to Tuple
// TODO: delegate cty.Set to Set
// TODO: delegate cty.List to List
editRange := lv.expr.Range()
if editRange.End.Line != pos.Line {
// account for quotes or brackets that are not closed
editRange.End = pos
}

if !editRange.ContainsPos(pos) {
// account for trailing character(s) which doesn't appear in AST
// such as dot, opening bracket etc.
editRange.End = pos
}

cd := lv.cons.EmptyCompletionData(ctx, 1, 0)
return []lang.Candidate{
{
Label: labelForLiteralValue(lv.cons.Value, false),
Detail: typ.FriendlyName(),
Kind: candidateKindForType(typ),
TextEdit: lang.TextEdit{
Range: editRange,
NewText: cd.NewText,
Snippet: cd.Snippet,
},
TriggerSuggest: cd.TriggerSuggest,
},
}

// Avoid partial completion inside complex types for now
}

func (lt LiteralValue) completeBoolAtPos(ctx context.Context, pos hcl.Pos) []lang.Candidate {
switch eType := lt.expr.(type) {

case *hclsyntax.ScopeTraversalExpr:
prefixLen := pos.Byte - eType.Range().Start.Byte
prefix := eType.Traversal.RootName()[0:prefixLen]
return boolLiteralCandidates(prefix, eType.Range())

case *hclsyntax.LiteralValueExpr:
if eType.Val.Type() == cty.Bool {
value := "false"
if eType.Val.True() {
value = "true"
}
prefixLen := pos.Byte - eType.Range().Start.Byte
prefix := value[0:prefixLen]
return boolLiteralCandidates(prefix, eType.Range())
}
}

return nil
return []lang.Candidate{}
}
Loading

0 comments on commit b8f42e4

Please sign in to comment.