Skip to content

Commit

Permalink
Refactor hoverAtPos to use collected origins
Browse files Browse the repository at this point in the history
  • Loading branch information
dbanck committed Nov 11, 2022
1 parent 01d62d4 commit be64fc6
Show file tree
Hide file tree
Showing 3 changed files with 213 additions and 24 deletions.
58 changes: 34 additions & 24 deletions decoder/hover.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ func (d *PathDecoder) HoverAtPos(ctx context.Context, filename string, pos hcl.P
return nil, &NoSchemaError{}
}

data, err := d.hoverAtPos(ctx, rootBody, d.pathCtx.Schema, pos)
data, err := d.hoverAtPos(ctx, rootBody, d.pathCtx.Schema, filename, pos)
if err != nil {
return nil, err
}

return data, nil
}

func (d *PathDecoder) hoverAtPos(ctx context.Context, body *hclsyntax.Body, bodySchema *schema.BodySchema, pos hcl.Pos) (*lang.HoverData, error) {
func (d *PathDecoder) hoverAtPos(ctx context.Context, body *hclsyntax.Body, bodySchema *schema.BodySchema, file string, pos hcl.Pos) (*lang.HoverData, error) {
if bodySchema == nil {
return nil, nil
}
Expand Down Expand Up @@ -92,7 +92,7 @@ func (d *PathDecoder) hoverAtPos(ctx context.Context, body *hclsyntax.Body, body

if attr.Expr.Range().ContainsPos(pos) {
exprCons := ExprConstraints(aSchema.Expr)
data, err := d.hoverDataForExpr(ctx, attr.Expr, exprCons, 0, pos)
data, err := d.hoverDataForExpr(ctx, attr.Expr, exprCons, 0, file, pos)
if err != nil {
return nil, &PositionalError{
Filename: filename,
Expand Down Expand Up @@ -160,7 +160,7 @@ func (d *PathDecoder) hoverAtPos(ctx context.Context, body *hclsyntax.Body, body
return nil, err
}

return d.hoverAtPos(ctx, block.Body, mergedSchema, pos)
return d.hoverAtPos(ctx, block.Body, mergedSchema, file, pos)
}
}
}
Expand Down Expand Up @@ -247,7 +247,7 @@ func (d *PathDecoder) hoverContentForBlock(bType string, schema *schema.BlockSch
}
}

func (d *PathDecoder) hoverDataForExpr(ctx context.Context, expr hcl.Expression, constraints ExprConstraints, nestingLvl int, pos hcl.Pos) (*lang.HoverData, error) {
func (d *PathDecoder) hoverDataForExpr(ctx context.Context, expr hcl.Expression, constraints ExprConstraints, nestingLvl int, file string, pos hcl.Pos) (*lang.HoverData, error) {
switch e := expr.(type) {
case *hclsyntax.ScopeTraversalExpr:
kw, ok := constraints.KeywordExpr()
Expand All @@ -266,7 +266,7 @@ func (d *PathDecoder) hoverDataForExpr(ctx context.Context, expr hcl.Expression,

tes, ok := constraints.TraversalExprs()
if ok {
content, err := d.hoverContentForTraversalExpr(e.AsTraversal(), tes)
content, err := d.hoverContentForTraversalExpr(e.AsTraversal(), tes, file, pos)
if err != nil {
return nil, err
}
Expand All @@ -293,7 +293,7 @@ func (d *PathDecoder) hoverDataForExpr(ctx context.Context, expr hcl.Expression,
}
case *hclsyntax.TemplateExpr:
if e.IsStringLiteral() {
data, err := d.hoverDataForExpr(ctx, e.Parts[0], constraints, nestingLvl, pos)
data, err := d.hoverDataForExpr(ctx, e.Parts[0], constraints, nestingLvl, file, pos)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -327,7 +327,7 @@ func (d *PathDecoder) hoverDataForExpr(ctx context.Context, expr hcl.Expression,
}
}
case *hclsyntax.TemplateWrapExpr:
data, err := d.hoverDataForExpr(ctx, e.Wrapped, constraints, nestingLvl, pos)
data, err := d.hoverDataForExpr(ctx, e.Wrapped, constraints, nestingLvl, file, pos)
if err != nil {
return nil, err
}
Expand All @@ -352,7 +352,7 @@ func (d *PathDecoder) hoverDataForExpr(ctx context.Context, expr hcl.Expression,
if ok {
for _, elemExpr := range e.Exprs {
if elemExpr.Range().ContainsPos(pos) {
return d.hoverDataForExpr(ctx, elemExpr, ExprConstraints(se.Elem), nestingLvl, pos)
return d.hoverDataForExpr(ctx, elemExpr, ExprConstraints(se.Elem), nestingLvl, file, pos)
}
}
content := fmt.Sprintf("_%s_", se.FriendlyName())
Expand All @@ -368,7 +368,7 @@ func (d *PathDecoder) hoverDataForExpr(ctx context.Context, expr hcl.Expression,
if ok {
for _, elemExpr := range e.Exprs {
if elemExpr.Range().ContainsPos(pos) {
return d.hoverDataForExpr(ctx, elemExpr, ExprConstraints(le.Elem), nestingLvl, pos)
return d.hoverDataForExpr(ctx, elemExpr, ExprConstraints(le.Elem), nestingLvl, file, pos)
}
}
content := fmt.Sprintf("_%s_", le.FriendlyName())
Expand All @@ -388,7 +388,7 @@ func (d *PathDecoder) hoverDataForExpr(ctx context.Context, expr hcl.Expression,
return nil, &ConstraintMismatch{elemExpr}
}
ec := ExprConstraints(te.Elems[i])
return d.hoverDataForExpr(ctx, elemExpr, ec, nestingLvl, pos)
return d.hoverDataForExpr(ctx, elemExpr, ec, nestingLvl, file, pos)
}
}
content := fmt.Sprintf("_%s_", te.FriendlyName())
Expand Down Expand Up @@ -425,7 +425,7 @@ func (d *PathDecoder) hoverDataForExpr(ctx context.Context, expr hcl.Expression,
case *hclsyntax.ObjectConsExpr:
objExpr, ok := constraints.ObjectExpr()
if ok {
return d.hoverDataForObjectExpr(ctx, e, objExpr, nestingLvl, pos)
return d.hoverDataForObjectExpr(ctx, e, objExpr, nestingLvl, file, pos)
}
mapExpr, ok := constraints.MapExpr()
if ok {
Expand Down Expand Up @@ -501,7 +501,7 @@ func (d *PathDecoder) hoverDataForExpr(ctx context.Context, expr hcl.Expression,
return nil, fmt.Errorf("unsupported expression (%T)", expr)
}

func (d *PathDecoder) hoverDataForObjectExpr(ctx context.Context, objExpr *hclsyntax.ObjectConsExpr, oe schema.ObjectExpr, nestingLvl int, pos hcl.Pos) (*lang.HoverData, error) {
func (d *PathDecoder) hoverDataForObjectExpr(ctx context.Context, objExpr *hclsyntax.ObjectConsExpr, oe schema.ObjectExpr, nestingLvl int, file string, pos hcl.Pos) (*lang.HoverData, error) {
declaredAttributes := make(map[string]hclsyntax.Expression, 0)
for _, item := range objExpr.Items {
key, _ := item.KeyExpr.Value(nil)
Expand All @@ -517,7 +517,7 @@ func (d *PathDecoder) hoverDataForObjectExpr(ctx context.Context, objExpr *hclsy
}

if item.ValueExpr.Range().ContainsPos(pos) {
return d.hoverDataForExpr(ctx, item.ValueExpr, ExprConstraints(attr.Expr), nestingLvl+1, pos)
return d.hoverDataForExpr(ctx, item.ValueExpr, ExprConstraints(attr.Expr), nestingLvl+1, file, pos)
}

itemRng := hcl.RangeBetween(item.KeyExpr.Range(), item.ValueExpr.Range())
Expand Down Expand Up @@ -558,7 +558,7 @@ func (d *PathDecoder) hoverDataForObjectExpr(ctx context.Context, objExpr *hclsy
attrData := ec.FriendlyName()

if attrExpr, ok := declaredAttributes[name]; ok {
data, err := d.hoverDataForExpr(ctx, attrExpr, ExprConstraints(ec), nestingLvl+1, pos)
data, err := d.hoverDataForExpr(ctx, attrExpr, ExprConstraints(ec), nestingLvl+1, file, pos)
if err == nil && data.Content.Value != "" {
attrData = data.Content.Value
}
Expand Down Expand Up @@ -625,19 +625,29 @@ func stringValFromTemplateExpr(tplExpr *hclsyntax.TemplateExpr) (cty.Value, bool
return cty.StringVal(value), true
}

func (d *PathDecoder) hoverContentForTraversalExpr(traversal hcl.Traversal, tes []schema.TraversalExpr) (string, error) {
origin, err := reference.TraversalToLocalOrigin(traversal, tes)
if err != nil {
return "", nil
func (d *PathDecoder) hoverContentForTraversalExpr(traversal hcl.Traversal, tes []schema.TraversalExpr, file string, pos hcl.Pos) (string, error) {
// TODO? use traversal.SourceRange()
origins, ok := d.pathCtx.ReferenceOrigins.AtPos(file, pos)
if !ok {
return "", &reference.NoOriginFound{}
}

targets, ok := d.pathCtx.ReferenceTargets.Match(origin)
if !ok {
return "", &reference.NoTargetFound{}
for _, origin := range origins {
matchableOrigin, ok := origin.(reference.MatchableOrigin)
if !ok {
continue
}
targets, ok := d.pathCtx.ReferenceTargets.Match(matchableOrigin)
if !ok {
// target not found
continue
}

// TODO: Reflect additional found targets here?
return hoverContentForReferenceTarget(targets[0])
}

// TODO: Reflect additional found targets here?
return hoverContentForReferenceTarget(targets[0])
return "", &reference.NoTargetFound{}
}

func hoverContentForReferenceTarget(ref reference.Target) (string, error) {
Expand Down
133 changes: 133 additions & 0 deletions decoder/hover_expressions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1309,6 +1309,7 @@ func TestDecoder_HoverAtPos_traversalExpressions(t *testing.T) {
name string
attrSchema map[string]*schema.AttributeSchema
refs reference.Targets
origins reference.Origins
cfg string
pos hcl.Pos
expectedData *lang.HoverData
Expand All @@ -1324,6 +1325,32 @@ func TestDecoder_HoverAtPos_traversalExpressions(t *testing.T) {
},
},
reference.Targets{},
reference.Origins{
reference.LocalOrigin{
Addr: lang.Address{
lang.RootStep{Name: "var"},
lang.AttrStep{Name: "blah"},
},
Range: hcl.Range{
Filename: "test.tf",
Start: hcl.Pos{
Line: 1,
Column: 8,
Byte: 7,
},
End: hcl.Pos{
Line: 1,
Column: 16,
Byte: 15,
},
},
Constraints: reference.OriginConstraints{
reference.OriginConstraint{
OfType: cty.String,
},
},
},
},
`attr = var.blah`,
hcl.Pos{Line: 1, Column: 10, Byte: 9},
nil,
Expand All @@ -1347,6 +1374,32 @@ func TestDecoder_HoverAtPos_traversalExpressions(t *testing.T) {
Type: cty.Bool,
},
},
reference.Origins{
reference.LocalOrigin{
Addr: lang.Address{
lang.RootStep{Name: "var"},
lang.AttrStep{Name: "blah"},
},
Range: hcl.Range{
Filename: "test.tf",
Start: hcl.Pos{
Line: 1,
Column: 8,
Byte: 7,
},
End: hcl.Pos{
Line: 1,
Column: 16,
Byte: 15,
},
},
Constraints: reference.OriginConstraints{
reference.OriginConstraint{
OfType: cty.String,
},
},
},
},
`attr = var.blah`,
hcl.Pos{Line: 1, Column: 10, Byte: 9},
nil,
Expand All @@ -1370,6 +1423,32 @@ func TestDecoder_HoverAtPos_traversalExpressions(t *testing.T) {
Type: cty.String,
},
},
reference.Origins{
reference.LocalOrigin{
Addr: lang.Address{
lang.RootStep{Name: "var"},
lang.AttrStep{Name: "blah"},
},
Range: hcl.Range{
Filename: "test.tf",
Start: hcl.Pos{
Line: 1,
Column: 8,
Byte: 7,
},
End: hcl.Pos{
Line: 1,
Column: 16,
Byte: 15,
},
},
Constraints: reference.OriginConstraints{
reference.OriginConstraint{
OfType: cty.String,
},
},
},
},
`attr = var.blah`,
hcl.Pos{Line: 1, Column: 10, Byte: 9},
&lang.HoverData{
Expand Down Expand Up @@ -1408,6 +1487,33 @@ func TestDecoder_HoverAtPos_traversalExpressions(t *testing.T) {
Type: cty.DynamicPseudoType,
},
},
reference.Origins{
reference.LocalOrigin{
Addr: lang.Address{
lang.RootStep{Name: "var"},
lang.AttrStep{Name: "foo"},
lang.AttrStep{Name: "bar"},
},
Range: hcl.Range{
Filename: "test.tf",
Start: hcl.Pos{
Line: 1,
Column: 8,
Byte: 7,
},
End: hcl.Pos{
Line: 1,
Column: 19,
Byte: 18,
},
},
Constraints: reference.OriginConstraints{
reference.OriginConstraint{
OfType: cty.String,
},
},
},
},
`attr = var.foo.bar`,
hcl.Pos{Line: 1, Column: 10, Byte: 9},
&lang.HoverData{
Expand Down Expand Up @@ -1447,6 +1553,32 @@ func TestDecoder_HoverAtPos_traversalExpressions(t *testing.T) {
Name: "special",
},
},
reference.Origins{
reference.LocalOrigin{
Addr: lang.Address{
lang.RootStep{Name: "var"},
lang.AttrStep{Name: "foo"},
},
Range: hcl.Range{
Filename: "test.tf",
Start: hcl.Pos{
Line: 1,
Column: 8,
Byte: 7,
},
End: hcl.Pos{
Line: 1,
Column: 15,
Byte: 14,
},
},
Constraints: reference.OriginConstraints{
reference.OriginConstraint{
OfScopeId: lang.ScopeId("foo"),
},
},
},
},
`attr = var.foo`,
hcl.Pos{Line: 1, Column: 10, Byte: 9},
&lang.HoverData{
Expand Down Expand Up @@ -1480,6 +1612,7 @@ func TestDecoder_HoverAtPos_traversalExpressions(t *testing.T) {
d := testPathDecoder(t, &PathContext{
Schema: bodySchema,
ReferenceTargets: tc.refs,
ReferenceOrigins: tc.origins,
Files: map[string]*hcl.File{
"test.tf": f,
},
Expand Down
Loading

0 comments on commit be64fc6

Please sign in to comment.