1
1
package decoder
2
2
3
3
import (
4
+ "context"
4
5
"fmt"
5
6
"sort"
6
7
"strings"
7
8
9
+ "github.com/zclconf/go-cty/cty"
10
+
11
+ icontext "github.com/hashicorp/hcl-lang/context"
8
12
"github.com/hashicorp/hcl-lang/lang"
9
13
"github.com/hashicorp/hcl-lang/reference"
10
14
"github.com/hashicorp/hcl-lang/schema"
11
15
"github.com/hashicorp/hcl/v2"
12
16
"github.com/hashicorp/hcl/v2/hclsyntax"
13
- "github.com/zclconf/go-cty/cty"
14
17
)
15
18
16
- func (d * PathDecoder ) HoverAtPos (filename string , pos hcl.Pos ) (* lang.HoverData , error ) {
19
+ func (d * PathDecoder ) HoverAtPos (ctx context. Context , filename string , pos hcl.Pos ) (* lang.HoverData , error ) {
17
20
f , err := d .fileByName (filename )
18
21
if err != nil {
19
22
return nil , err
@@ -28,23 +31,46 @@ func (d *PathDecoder) HoverAtPos(filename string, pos hcl.Pos) (*lang.HoverData,
28
31
return nil , & NoSchemaError {}
29
32
}
30
33
31
- data , err := d .hoverAtPos (rootBody , d .pathCtx .Schema , pos )
34
+ data , err := d .hoverAtPos (ctx , rootBody , d .pathCtx .Schema , pos )
32
35
if err != nil {
33
36
return nil , err
34
37
}
35
38
36
39
return data , nil
37
40
}
38
41
39
- func (d * PathDecoder ) hoverAtPos (body * hclsyntax.Body , bodySchema * schema.BodySchema , pos hcl.Pos ) (* lang.HoverData , error ) {
42
+ func (d * PathDecoder ) hoverAtPos (ctx context. Context , body * hclsyntax.Body , bodySchema * schema.BodySchema , pos hcl.Pos ) (* lang.HoverData , error ) {
40
43
if bodySchema == nil {
41
44
return nil , nil
42
45
}
43
46
44
47
filename := body .Range ().Filename
45
48
49
+ if bodySchema .Extensions != nil {
50
+ ctx = icontext .WithExtensions (ctx , bodySchema .Extensions )
51
+ if bodySchema .Extensions .Count {
52
+ if _ , ok := body .Attributes ["count" ]; ok {
53
+ // append to context we need count provided
54
+ ctx = icontext .WithActiveCount (ctx )
55
+ }
56
+ }
57
+ }
58
+
46
59
for name , attr := range body .Attributes {
47
60
if attr .Range ().ContainsPos (pos ) {
61
+
62
+ if bodySchema .Extensions != nil {
63
+ if name == "count" && bodySchema .Extensions .Count {
64
+ return & lang.HoverData {
65
+ Content : lang.MarkupContent {
66
+ Kind : lang .MarkdownKind ,
67
+ Value : "**count** _optional, number_\n \n The distinct index number (starting with 0) corresponding to the instance" ,
68
+ },
69
+ Range : attr .Range (),
70
+ }, nil
71
+ }
72
+ }
73
+
48
74
aSchema , ok := bodySchema .Attributes [attr .Name ]
49
75
if ! ok {
50
76
if bodySchema .AnyAttribute == nil {
@@ -66,7 +92,7 @@ func (d *PathDecoder) hoverAtPos(body *hclsyntax.Body, bodySchema *schema.BodySc
66
92
67
93
if attr .Expr .Range ().ContainsPos (pos ) {
68
94
exprCons := ExprConstraints (aSchema .Expr )
69
- data , err := d .hoverDataForExpr (attr .Expr , exprCons , 0 , pos )
95
+ data , err := d .hoverDataForExpr (ctx , attr .Expr , exprCons , 0 , pos )
70
96
if err != nil {
71
97
return nil , & PositionalError {
72
98
Filename : filename ,
@@ -128,7 +154,7 @@ func (d *PathDecoder) hoverAtPos(body *hclsyntax.Body, bodySchema *schema.BodySc
128
154
return nil , err
129
155
}
130
156
131
- return d .hoverAtPos (block .Body , mergedSchema , pos )
157
+ return d .hoverAtPos (ctx , block .Body , mergedSchema , pos )
132
158
}
133
159
}
134
160
}
@@ -215,7 +241,7 @@ func (d *PathDecoder) hoverContentForBlock(bType string, schema *schema.BlockSch
215
241
}
216
242
}
217
243
218
- func (d * PathDecoder ) hoverDataForExpr (expr hcl.Expression , constraints ExprConstraints , nestingLvl int , pos hcl.Pos ) (* lang.HoverData , error ) {
244
+ func (d * PathDecoder ) hoverDataForExpr (ctx context. Context , expr hcl.Expression , constraints ExprConstraints , nestingLvl int , pos hcl.Pos ) (* lang.HoverData , error ) {
219
245
switch e := expr .(type ) {
220
246
case * hclsyntax.ScopeTraversalExpr :
221
247
kw , ok := constraints .KeywordExpr ()
@@ -232,6 +258,21 @@ func (d *PathDecoder) hoverDataForExpr(expr hcl.Expression, constraints ExprCons
232
258
}, nil
233
259
}
234
260
261
+ address , _ := lang .TraversalToAddress (e .AsTraversal ())
262
+ if address .Equals (lang.Address {
263
+ lang.RootStep {
264
+ Name : "count" ,
265
+ },
266
+ lang.AttrStep {
267
+ Name : "index" ,
268
+ },
269
+ }) && icontext .ActiveCountFromContext (ctx ) {
270
+ return & lang.HoverData {
271
+ Content : lang .Markdown ("**count.index** fooooo" ),
272
+ Range : expr .Range (),
273
+ }, nil
274
+ }
275
+
235
276
tes , ok := constraints .TraversalExprs ()
236
277
if ok {
237
278
content , err := d .hoverContentForTraversalExpr (e .AsTraversal (), tes )
@@ -261,7 +302,7 @@ func (d *PathDecoder) hoverDataForExpr(expr hcl.Expression, constraints ExprCons
261
302
}
262
303
case * hclsyntax.TemplateExpr :
263
304
if e .IsStringLiteral () {
264
- data , err := d .hoverDataForExpr (e .Parts [0 ], constraints , nestingLvl , pos )
305
+ data , err := d .hoverDataForExpr (ctx , e .Parts [0 ], constraints , nestingLvl , pos )
265
306
if err != nil {
266
307
return nil , err
267
308
}
@@ -295,7 +336,7 @@ func (d *PathDecoder) hoverDataForExpr(expr hcl.Expression, constraints ExprCons
295
336
}
296
337
}
297
338
case * hclsyntax.TemplateWrapExpr :
298
- data , err := d .hoverDataForExpr (e .Wrapped , constraints , nestingLvl , pos )
339
+ data , err := d .hoverDataForExpr (ctx , e .Wrapped , constraints , nestingLvl , pos )
299
340
if err != nil {
300
341
return nil , err
301
342
}
@@ -320,7 +361,7 @@ func (d *PathDecoder) hoverDataForExpr(expr hcl.Expression, constraints ExprCons
320
361
if ok {
321
362
for _ , elemExpr := range e .Exprs {
322
363
if elemExpr .Range ().ContainsPos (pos ) {
323
- return d .hoverDataForExpr (elemExpr , ExprConstraints (se .Elem ), nestingLvl , pos )
364
+ return d .hoverDataForExpr (ctx , elemExpr , ExprConstraints (se .Elem ), nestingLvl , pos )
324
365
}
325
366
}
326
367
content := fmt .Sprintf ("_%s_" , se .FriendlyName ())
@@ -336,7 +377,7 @@ func (d *PathDecoder) hoverDataForExpr(expr hcl.Expression, constraints ExprCons
336
377
if ok {
337
378
for _ , elemExpr := range e .Exprs {
338
379
if elemExpr .Range ().ContainsPos (pos ) {
339
- return d .hoverDataForExpr (elemExpr , ExprConstraints (le .Elem ), nestingLvl , pos )
380
+ return d .hoverDataForExpr (ctx , elemExpr , ExprConstraints (le .Elem ), nestingLvl , pos )
340
381
}
341
382
}
342
383
content := fmt .Sprintf ("_%s_" , le .FriendlyName ())
@@ -356,7 +397,7 @@ func (d *PathDecoder) hoverDataForExpr(expr hcl.Expression, constraints ExprCons
356
397
return nil , & ConstraintMismatch {elemExpr }
357
398
}
358
399
ec := ExprConstraints (te .Elems [i ])
359
- return d .hoverDataForExpr (elemExpr , ec , nestingLvl , pos )
400
+ return d .hoverDataForExpr (ctx , elemExpr , ec , nestingLvl , pos )
360
401
}
361
402
}
362
403
content := fmt .Sprintf ("_%s_" , te .FriendlyName ())
@@ -393,7 +434,7 @@ func (d *PathDecoder) hoverDataForExpr(expr hcl.Expression, constraints ExprCons
393
434
case * hclsyntax.ObjectConsExpr :
394
435
objExpr , ok := constraints .ObjectExpr ()
395
436
if ok {
396
- return d .hoverDataForObjectExpr (e , objExpr , nestingLvl , pos )
437
+ return d .hoverDataForObjectExpr (ctx , e , objExpr , nestingLvl , pos )
397
438
}
398
439
mapExpr , ok := constraints .MapExpr ()
399
440
if ok {
@@ -469,7 +510,7 @@ func (d *PathDecoder) hoverDataForExpr(expr hcl.Expression, constraints ExprCons
469
510
return nil , fmt .Errorf ("unsupported expression (%T)" , expr )
470
511
}
471
512
472
- func (d * PathDecoder ) hoverDataForObjectExpr (objExpr * hclsyntax.ObjectConsExpr , oe schema.ObjectExpr , nestingLvl int , pos hcl.Pos ) (* lang.HoverData , error ) {
513
+ func (d * PathDecoder ) hoverDataForObjectExpr (ctx context. Context , objExpr * hclsyntax.ObjectConsExpr , oe schema.ObjectExpr , nestingLvl int , pos hcl.Pos ) (* lang.HoverData , error ) {
473
514
declaredAttributes := make (map [string ]hclsyntax.Expression , 0 )
474
515
for _ , item := range objExpr .Items {
475
516
key , _ := item .KeyExpr .Value (nil )
@@ -485,7 +526,7 @@ func (d *PathDecoder) hoverDataForObjectExpr(objExpr *hclsyntax.ObjectConsExpr,
485
526
}
486
527
487
528
if item .ValueExpr .Range ().ContainsPos (pos ) {
488
- return d .hoverDataForExpr (item .ValueExpr , ExprConstraints (attr .Expr ), nestingLvl + 1 , pos )
529
+ return d .hoverDataForExpr (ctx , item .ValueExpr , ExprConstraints (attr .Expr ), nestingLvl + 1 , pos )
489
530
}
490
531
491
532
itemRng := hcl .RangeBetween (item .KeyExpr .Range (), item .ValueExpr .Range ())
@@ -526,7 +567,7 @@ func (d *PathDecoder) hoverDataForObjectExpr(objExpr *hclsyntax.ObjectConsExpr,
526
567
attrData := ec .FriendlyName ()
527
568
528
569
if attrExpr , ok := declaredAttributes [name ]; ok {
529
- data , err := d .hoverDataForExpr (attrExpr , ExprConstraints (ec ), nestingLvl + 1 , pos )
570
+ data , err := d .hoverDataForExpr (ctx , attrExpr , ExprConstraints (ec ), nestingLvl + 1 , pos )
530
571
if err == nil && data .Content .Value != "" {
531
572
attrData = data .Content .Value
532
573
}
0 commit comments