Skip to content

Commit

Permalink
decoder: Implement hover for Object
Browse files Browse the repository at this point in the history
  • Loading branch information
radeksimko committed Feb 16, 2023
1 parent 9f2f36b commit 654d10d
Show file tree
Hide file tree
Showing 4 changed files with 469 additions and 16 deletions.
5 changes: 0 additions & 5 deletions decoder/expr_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@ type Object struct {
pathCtx *PathContext
}

func (obj Object) HoverAtPos(ctx context.Context, pos hcl.Pos) *lang.HoverData {
// TODO
return nil
}

func (obj Object) SemanticTokens(ctx context.Context) []lang.SemanticToken {
// TODO
return nil
Expand Down
89 changes: 89 additions & 0 deletions decoder/expr_object_hover.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package decoder

import (
"context"
"fmt"

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

func (obj Object) HoverAtPos(ctx context.Context, pos hcl.Pos) *lang.HoverData {
eType, ok := obj.expr.(*hclsyntax.ObjectConsExpr)
if !ok {
return nil
}

for _, item := range eType.Items {
attrName, _, ok := getRawObjectAttributeName(item.KeyExpr)
if !ok {
continue
}

aSchema, ok := obj.cons.Attributes[attrName]
if !ok {
// unknown attribute
return nil
}

if item.KeyExpr.Range().ContainsPos(pos) {
itemRng := hcl.RangeBetween(item.KeyExpr.Range(), item.ValueExpr.Range())
content := hoverContentForAttribute(attrName, aSchema)

return &lang.HoverData{
Content: content,
Range: itemRng,
}
}

if item.ValueExpr.Range().ContainsPos(pos) {
expr := newExpression(obj.pathCtx, item.ValueExpr, aSchema.Constraint)
return expr.HoverAtPos(ctx, pos)
}
}

content := hoverDataForObjectAttributes(obj.cons.Attributes)
content += fmt.Sprintf("_%s_", obj.cons.FriendlyName())
if obj.cons.Description.Value != "" {
content += "\n\n" + obj.cons.Description.Value
}

return &lang.HoverData{
Content: lang.Markdown(content),
Range: eType.Range(),
}
}

func hoverContentForAttribute(name string, aSchema *schema.AttributeSchema) lang.MarkupContent {
value := fmt.Sprintf("**%s** _%s_", name, detailForAttribute(aSchema))
if aSchema.Description.Value != "" {
value += fmt.Sprintf("\n\n%s", aSchema.Description.Value)
}
return lang.MarkupContent{
Kind: lang.MarkdownKind,
Value: value,
}
}

func hoverDataForObjectAttributes(attributes schema.ObjectAttributes) string {
if len(attributes) == 0 {
return ""
}

data := "```\n{\n"
for name, attr := range attributes {
exprData := attr.Constraint.FriendlyName()
// TODO: expand and render any "expandable" constraints
// - Object, Map, List, Set, Tuple
// Maybe introduce schema.Constraint.EmptyHoverData(nestingLevel int) *lang.HoverData

if attr.IsOptional {
exprData = fmt.Sprintf("optional, %s", exprData)
}
data += fmt.Sprintf("%s%s = %s\n", " ", name, exprData)
}
data += "}\n```\n"
return data
}
Loading

0 comments on commit 654d10d

Please sign in to comment.