Skip to content

Commit e6f0252

Browse files
authored
Avoid completing static block inside a dynamic label (#165)
* Add test case for label completion * Only check block length if there is no dependent body * Turn else into else if
1 parent 13e06fb commit e6f0252

File tree

2 files changed

+68
-10
lines changed

2 files changed

+68
-10
lines changed

decoder/body_extensions_test.go

Lines changed: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1695,6 +1695,7 @@ func TestCompletionAtPos_BodySchema_Extensions_DynamicBlock(t *testing.T) {
16951695
cfg string
16961696
pos hcl.Pos
16971697
expectedCandidates lang.Candidates
1698+
expectedErr string
16981699
}{
16991700
{
17001701
"dynamic block does not complete if not enabled",
@@ -1728,6 +1729,7 @@ resource "aws_elastic_beanstalk_environment" "example" {
17281729
Byte: 77,
17291730
},
17301731
lang.CompleteCandidates([]lang.Candidate{}),
1732+
"",
17311733
},
17321734
{
17331735
"dynamic block does not complete without blocks",
@@ -1783,6 +1785,7 @@ resource "aws_elastic_beanstalk_environment" "example" {
17831785
Kind: lang.AttributeCandidateKind,
17841786
},
17851787
}),
1788+
"",
17861789
},
17871790
{
17881791
"dynamic block completion",
@@ -1878,6 +1881,7 @@ resource "aws_elastic_beanstalk_environment" "example" {
18781881
},
18791882
},
18801883
}),
1884+
"",
18811885
},
18821886
{
18831887
"dynamic block inner completion",
@@ -2001,6 +2005,7 @@ resource "aws_elastic_beanstalk_environment" "example" {
20012005
},
20022006
},
20032007
}),
2008+
"",
20042009
},
20052010
{
20062011
"dynamic block content attribute completion",
@@ -2074,6 +2079,7 @@ resource "aws_elastic_beanstalk_environment" "example" {
20742079
},
20752080
},
20762081
}),
2082+
"",
20772083
},
20782084
{
20792085
"dynamic block label only completes dependent blocks",
@@ -2136,6 +2142,52 @@ resource "aws_elastic_beanstalk_environment" "example" {
21362142
},
21372143
},
21382144
}),
2145+
"",
2146+
},
2147+
{
2148+
"dynamic block label never completes static blocks",
2149+
&schema.BodySchema{
2150+
Blocks: map[string]*schema.BlockSchema{
2151+
"resource": {
2152+
Labels: []*schema.LabelSchema{
2153+
{
2154+
Name: "type",
2155+
IsDepKey: true,
2156+
Completable: true,
2157+
},
2158+
{Name: "name"},
2159+
},
2160+
Body: &schema.BodySchema{
2161+
Extensions: &schema.BodyExtensions{
2162+
DynamicBlocks: true,
2163+
},
2164+
Blocks: map[string]*schema.BlockSchema{
2165+
"lifecycle": {
2166+
Body: schema.NewBodySchema(),
2167+
},
2168+
},
2169+
},
2170+
DependentBody: map[schema.SchemaKey]*schema.BodySchema{
2171+
schema.NewSchemaKey(schema.DependencyKeys{
2172+
Labels: []schema.LabelDependent{
2173+
{Index: 0, Value: "aws_instance"},
2174+
},
2175+
}): {
2176+
Blocks: make(map[string]*schema.BlockSchema, 0),
2177+
},
2178+
},
2179+
},
2180+
},
2181+
},
2182+
`resource "aws_instance" "example" {
2183+
name = "example"
2184+
dynamic "" {
2185+
2186+
}
2187+
}`,
2188+
hcl.Pos{Line: 3, Column: 12, Byte: 66},
2189+
lang.CompleteCandidates([]lang.Candidate{}),
2190+
`test.tf (3,12): unknown block type "dynamic"`,
21392191
},
21402192
// completion nesting should work
21412193
{
@@ -2245,6 +2297,7 @@ resource "aws_elastic_beanstalk_environment" "example" {
22452297
},
22462298
},
22472299
}),
2300+
"",
22482301
},
22492302
// completion after the thing =
22502303
{
@@ -2333,6 +2386,7 @@ resource "aws_elastic_beanstalk_environment" "example" {
23332386
},
23342387
},
23352388
}),
2389+
"",
23362390
},
23372391
// check allows more than one dynamic
23382392
{
@@ -2409,6 +2463,7 @@ resource "aws_elastic_beanstalk_environment" "example" {
24092463
},
24102464
},
24112465
}),
2466+
"",
24122467
},
24132468
// allows dynamic blocks in blocks
24142469
{
@@ -2496,6 +2551,7 @@ resource "aws_elastic_beanstalk_environment" "example" {
24962551
},
24972552
},
24982553
}),
2554+
"",
24992555
},
25002556
// never complete dynamic as a dynamic label
25012557
{
@@ -2562,6 +2618,7 @@ resource "aws_elastic_beanstalk_environment" "example" {
25622618
},
25632619
},
25642620
}),
2621+
"",
25652622
},
25662623
}
25672624

@@ -2576,14 +2633,17 @@ resource "aws_elastic_beanstalk_environment" "example" {
25762633
},
25772634
})
25782635

2579-
// We're triggering completion twice her, to cover any unintended side effects
2580-
_, err := d.CandidatesAtPos(ctx, "test.tf", tc.pos)
2581-
if err != nil {
2582-
t.Fatal(err)
2583-
}
25842636
candidates, err := d.CandidatesAtPos(ctx, "test.tf", tc.pos)
2637+
25852638
if err != nil {
2586-
t.Fatal(err)
2639+
if tc.expectedErr != "" && err.Error() != tc.expectedErr {
2640+
t.Fatalf("unexpected error: %q\nexpected: %q\n",
2641+
err, tc.expectedErr)
2642+
} else if tc.expectedErr == "" {
2643+
t.Fatal(err)
2644+
}
2645+
} else if tc.expectedErr != "" {
2646+
t.Fatalf("expected error: %q", tc.expectedErr)
25872647
}
25882648

25892649
if diff := cmp.Diff(tc.expectedCandidates, candidates); diff != "" {

decoder/decoder.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,6 @@ func mergeBlockBodySchemas(block *hcl.Block, blockSchema *schema.BlockSchema) (*
5050
mergedSchema.ImpliedOrigins = make([]schema.ImpliedOrigin, 0)
5151
}
5252

53-
if mergedSchema.Extensions != nil && mergedSchema.Extensions.DynamicBlocks && len(mergedSchema.Blocks) > 0 {
54-
mergedSchema.Blocks["dynamic"] = buildDynamicBlockSchema(mergedSchema)
55-
}
56-
5753
depSchema, _, ok := NewBlockSchema(blockSchema).DependentBodySchema(block)
5854
if ok {
5955
for name, attr := range depSchema.Attributes {
@@ -97,6 +93,8 @@ func mergeBlockBodySchemas(block *hcl.Block, blockSchema *schema.BlockSchema) (*
9793
if depSchema.Extensions != nil {
9894
mergedSchema.Extensions = depSchema.Extensions.Copy()
9995
}
96+
} else if !ok && mergedSchema.Extensions != nil && mergedSchema.Extensions.DynamicBlocks && len(mergedSchema.Blocks) > 0 {
97+
mergedSchema.Blocks["dynamic"] = buildDynamicBlockSchema(mergedSchema)
10098
}
10199

102100
return mergedSchema, nil

0 commit comments

Comments
 (0)