@@ -39,7 +39,7 @@ func (r *TerraformDeprecatedInterpolationRule) Link() string {
39
39
40
40
// Check emits issues on the deprecated interpolation syntax.
41
41
// This logic is equivalent to the warning logic implemented in Terraform.
42
- // See https://github.com/hashicorp/terraform/pull/23348
42
+ // See https://github.com/hashicorp/terraform/blob/2ce03abe480c3f40d04bd0f289762721ea280848/configs/compat_shim.go#L144-L156
43
43
func (r * TerraformDeprecatedInterpolationRule ) Check (runner tflint.Runner ) error {
44
44
path , err := runner .GetModulePath ()
45
45
if err != nil {
@@ -50,29 +50,76 @@ func (r *TerraformDeprecatedInterpolationRule) Check(runner tflint.Runner) error
50
50
return nil
51
51
}
52
52
53
- diags := runner .WalkExpressions (tflint .ExprWalkFunc (func (expr hcl.Expression ) hcl.Diagnostics {
54
- return r .checkForDeprecatedInterpolationsInExpr (runner , expr )
55
- }))
53
+ diags := runner .WalkExpressions (& terraformDeprecatedInterpolationWalker {
54
+ runner : runner ,
55
+ rule : r ,
56
+ // create some capacity so that we can deal with simple expressions
57
+ // without any further allocation during our walk.
58
+ contextStack : make ([]terraformDeprecatedInterpolationContext , 0 , 16 ),
59
+ })
56
60
if diags .HasErrors () {
57
61
return diags
58
62
}
59
63
return nil
60
64
}
61
65
62
- func (r * TerraformDeprecatedInterpolationRule ) checkForDeprecatedInterpolationsInExpr (runner tflint.Runner , expr hcl.Expression ) hcl.Diagnostics {
63
- wrapExpr , ok := expr .(* hclsyntax.TemplateWrapExpr )
64
- if ! ok {
65
- return nil
66
+ type terraformDeprecatedInterpolationWalker struct {
67
+ runner tflint.Runner
68
+ rule * TerraformDeprecatedInterpolationRule
69
+ contextStack []terraformDeprecatedInterpolationContext
70
+ }
71
+
72
+ var _ tflint.ExprWalker = (* terraformDeprecatedInterpolationWalker )(nil )
73
+
74
+ type terraformDeprecatedInterpolationContext int
75
+
76
+ const (
77
+ terraformDeprecatedInterpolationContextNormal terraformDeprecatedInterpolationContext = 0
78
+ terraformDeprecatedInterpolationContextObjKey terraformDeprecatedInterpolationContext = 1
79
+ )
80
+
81
+ func (w * terraformDeprecatedInterpolationWalker ) Enter (expr hcl.Expression ) hcl.Diagnostics {
82
+ var err error
83
+
84
+ context := terraformDeprecatedInterpolationContextNormal
85
+ switch expr := expr .(type ) {
86
+ case * hclsyntax.ObjectConsKeyExpr :
87
+ context = terraformDeprecatedInterpolationContextObjKey
88
+ case * hclsyntax.TemplateWrapExpr :
89
+ // hclsyntax.TemplateWrapExpr is a special node type used by HCL only
90
+ // for the situation where a template is just a single interpolation,
91
+ // so we don't need to do anything further to distinguish that
92
+ // situation. ("normal" templates are *hclsyntax.TemplateExpr.)
93
+
94
+ const message = "Interpolation-only expressions are deprecated in Terraform v0.12.14"
95
+ switch w .currentContext () {
96
+ case terraformDeprecatedInterpolationContextObjKey :
97
+ // This case requires a different autofix strategy is needed
98
+ // to avoid ambiguous attribute keys.
99
+ err = w .runner .EmitIssueWithFix (
100
+ w .rule ,
101
+ message ,
102
+ expr .Range (),
103
+ func (f tflint.Fixer ) error {
104
+ return f .ReplaceText (expr .Range (), "(" , f .TextAt (expr .Wrapped .Range ()), ")" )
105
+ },
106
+ )
107
+ default :
108
+ err = w .runner .EmitIssueWithFix (
109
+ w .rule ,
110
+ message ,
111
+ expr .Range (),
112
+ func (f tflint.Fixer ) error {
113
+ return f .ReplaceText (expr .Range (), f .TextAt (expr .Wrapped .Range ()))
114
+ },
115
+ )
116
+ }
66
117
}
67
118
68
- err := runner .EmitIssueWithFix (
69
- r ,
70
- "Interpolation-only expressions are deprecated in Terraform v0.12.14" ,
71
- expr .Range (),
72
- func (f tflint.Fixer ) error {
73
- return f .ReplaceText (expr .Range (), f .TextAt (wrapExpr .Wrapped .Range ()))
74
- },
75
- )
119
+ // Note the context of the current node for when we potentially visit
120
+ // child nodes.
121
+ w .contextStack = append (w .contextStack , context )
122
+
76
123
if err != nil {
77
124
return hcl.Diagnostics {
78
125
{
@@ -84,3 +131,15 @@ func (r *TerraformDeprecatedInterpolationRule) checkForDeprecatedInterpolationsI
84
131
}
85
132
return nil
86
133
}
134
+
135
+ func (w * terraformDeprecatedInterpolationWalker ) Exit (expr hcl.Expression ) hcl.Diagnostics {
136
+ w .contextStack = w .contextStack [:len (w .contextStack )- 1 ]
137
+ return nil
138
+ }
139
+
140
+ func (w * terraformDeprecatedInterpolationWalker ) currentContext () terraformDeprecatedInterpolationContext {
141
+ if len (w .contextStack ) == 0 {
142
+ return terraformDeprecatedInterpolationContextNormal
143
+ }
144
+ return w .contextStack [len (w .contextStack )- 1 ]
145
+ }
0 commit comments