aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/hashicorp/hil/check_identifier.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/hashicorp/hil/check_identifier.go')
-rw-r--r--vendor/github.com/hashicorp/hil/check_identifier.go88
1 files changed, 88 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/hil/check_identifier.go b/vendor/github.com/hashicorp/hil/check_identifier.go
new file mode 100644
index 0000000..474f505
--- /dev/null
+++ b/vendor/github.com/hashicorp/hil/check_identifier.go
@@ -0,0 +1,88 @@
1package hil
2
3import (
4 "fmt"
5 "sync"
6
7 "github.com/hashicorp/hil/ast"
8)
9
10// IdentifierCheck is a SemanticCheck that checks that all identifiers
11// resolve properly and that the right number of arguments are passed
12// to functions.
13type IdentifierCheck struct {
14 Scope ast.Scope
15
16 err error
17 lock sync.Mutex
18}
19
20func (c *IdentifierCheck) Visit(root ast.Node) error {
21 c.lock.Lock()
22 defer c.lock.Unlock()
23 defer c.reset()
24 root.Accept(c.visit)
25 return c.err
26}
27
28func (c *IdentifierCheck) visit(raw ast.Node) ast.Node {
29 if c.err != nil {
30 return raw
31 }
32
33 switch n := raw.(type) {
34 case *ast.Call:
35 c.visitCall(n)
36 case *ast.VariableAccess:
37 c.visitVariableAccess(n)
38 case *ast.Output:
39 // Ignore
40 case *ast.LiteralNode:
41 // Ignore
42 default:
43 // Ignore
44 }
45
46 // We never do replacement with this visitor
47 return raw
48}
49
50func (c *IdentifierCheck) visitCall(n *ast.Call) {
51 // Look up the function in the map
52 function, ok := c.Scope.LookupFunc(n.Func)
53 if !ok {
54 c.createErr(n, fmt.Sprintf("unknown function called: %s", n.Func))
55 return
56 }
57
58 // Break up the args into what is variadic and what is required
59 args := n.Args
60 if function.Variadic && len(args) > len(function.ArgTypes) {
61 args = n.Args[:len(function.ArgTypes)]
62 }
63
64 // Verify the number of arguments
65 if len(args) != len(function.ArgTypes) {
66 c.createErr(n, fmt.Sprintf(
67 "%s: expected %d arguments, got %d",
68 n.Func, len(function.ArgTypes), len(n.Args)))
69 return
70 }
71}
72
73func (c *IdentifierCheck) visitVariableAccess(n *ast.VariableAccess) {
74 // Look up the variable in the map
75 if _, ok := c.Scope.LookupVar(n.Name); !ok {
76 c.createErr(n, fmt.Sprintf(
77 "unknown variable accessed: %s", n.Name))
78 return
79 }
80}
81
82func (c *IdentifierCheck) createErr(n ast.Node, str string) {
83 c.err = fmt.Errorf("%s: %s", n.Pos(), str)
84}
85
86func (c *IdentifierCheck) reset() {
87 c.err = nil
88}