|
1 | 1 | package rules |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "strings" |
| 5 | + |
4 | 6 | "github.com/hashicorp/hcl/v2" |
5 | 7 | "github.com/hashicorp/hcl/v2/hclsyntax" |
6 | 8 | "github.com/terraform-linters/tflint-plugin-sdk/tflint" |
@@ -53,61 +55,60 @@ func (r *TerraformDeprecatedIndexRule) Check(runner tflint.Runner) error { |
53 | 55 | return err |
54 | 56 | } |
55 | 57 |
|
56 | | - diags := runner.WalkExpressions(tflint.ExprWalkFunc(func(expr hcl.Expression) hcl.Diagnostics { |
57 | | - for _, variable := range expr.Variables() { |
58 | | - filename := expr.Range().Filename |
59 | | - file := files[filename] |
60 | | - |
61 | | - bytes := expr.Range().SliceBytes(file.Bytes) |
62 | | - |
63 | | - tokens, diags := hclsyntax.LexExpression(bytes, filename, variable.SourceRange().Start) |
64 | | - if diags.HasErrors() { |
65 | | - // HACK: If the expression cannot be lexed, try to lex it as a template. |
66 | | - // If it still cannot be lexed, return the original error. |
67 | | - tTokens, tDiags := hclsyntax.LexTemplate(bytes, filename, variable.SourceRange().Start) |
68 | | - if tDiags.HasErrors() { |
69 | | - return diags |
70 | | - } |
71 | | - |
72 | | - tokens = tTokens |
73 | | - } |
74 | | - |
75 | | - tokens = tokens[1:] |
76 | | - |
77 | | - for i, token := range tokens { |
78 | | - if token.Type == hclsyntax.TokenDot { |
79 | | - if len(tokens) == i+1 { |
80 | | - return nil |
81 | | - } |
82 | | - |
83 | | - next := tokens[i+1].Type |
84 | | - if next == hclsyntax.TokenNumberLit || next == hclsyntax.TokenStar { |
85 | | - if tokens[0].Type == hclsyntax.TokenDot { |
86 | | - if err := runner.EmitIssue( |
87 | | - r, |
88 | | - "List items should be accessed using square brackets", |
89 | | - expr.Range(), |
90 | | - ); err != nil { |
91 | | - return hcl.Diagnostics{ |
92 | | - { |
93 | | - Severity: hcl.DiagError, |
94 | | - Summary: "failed to call EmitIssue()", |
95 | | - Detail: err.Error(), |
96 | | - }, |
97 | | - } |
98 | | - } |
99 | | - } |
| 58 | + diags := runner.WalkExpressions(tflint.ExprWalkFunc(func(e hcl.Expression) hcl.Diagnostics { |
| 59 | + filename := e.Range().Filename |
| 60 | + file := files[filename] |
| 61 | + |
| 62 | + switch expr := e.(type) { |
| 63 | + case *hclsyntax.ScopeTraversalExpr: |
| 64 | + r.checkLegacyTraversalIndex(runner, expr.Traversal, file.Bytes) |
| 65 | + case *hclsyntax.RelativeTraversalExpr: |
| 66 | + r.checkLegacyTraversalIndex(runner, expr.Traversal, file.Bytes) |
| 67 | + case *hclsyntax.SplatExpr: |
| 68 | + if strings.HasPrefix(string(expr.MarkerRange.SliceBytes(file.Bytes)), ".") { |
| 69 | + if err := runner.EmitIssue( |
| 70 | + r, |
| 71 | + "List items should be accessed using square brackets", |
| 72 | + expr.MarkerRange, |
| 73 | + ); err != nil { |
| 74 | + return hcl.Diagnostics{ |
| 75 | + { |
| 76 | + Severity: hcl.DiagError, |
| 77 | + Summary: "failed to call EmitIssue()", |
| 78 | + Detail: err.Error(), |
| 79 | + }, |
100 | 80 | } |
101 | 81 | } |
102 | 82 | } |
103 | 83 | } |
104 | | - |
105 | 84 | return nil |
106 | 85 | })) |
107 | | - |
108 | 86 | if diags.HasErrors() { |
109 | 87 | return diags |
110 | 88 | } |
111 | 89 |
|
112 | 90 | return nil |
113 | 91 | } |
| 92 | + |
| 93 | +func (r *TerraformDeprecatedIndexRule) checkLegacyTraversalIndex(runner tflint.Runner, traversal hcl.Traversal, file []byte) hcl.Diagnostics { |
| 94 | + for _, t := range traversal { |
| 95 | + if _, ok := t.(hcl.TraverseIndex); ok { |
| 96 | + if strings.HasPrefix(string(t.SourceRange().SliceBytes(file)), ".") { |
| 97 | + if err := runner.EmitIssue( |
| 98 | + r, |
| 99 | + "List items should be accessed using square brackets", |
| 100 | + t.SourceRange(), |
| 101 | + ); err != nil { |
| 102 | + return hcl.Diagnostics{ |
| 103 | + { |
| 104 | + Severity: hcl.DiagError, |
| 105 | + Summary: "failed to call EmitIssue()", |
| 106 | + Detail: err.Error(), |
| 107 | + }, |
| 108 | + } |
| 109 | + } |
| 110 | + } |
| 111 | + } |
| 112 | + } |
| 113 | + return nil |
| 114 | +} |
0 commit comments