7 "github.com/hashicorp/hil/ast"
10 // IdentifierCheck is a SemanticCheck that checks that all identifiers
11 // resolve properly and that the right number of arguments are passed
13 type IdentifierCheck struct {
20 func (c *IdentifierCheck) Visit(root ast.Node) error {
28 func (c *IdentifierCheck) visit(raw ast.Node) ast.Node {
33 switch n := raw.(type) {
36 case *ast.VariableAccess:
37 c.visitVariableAccess(n)
40 case *ast.LiteralNode:
46 // We never do replacement with this visitor
50 func (c *IdentifierCheck) visitCall(n *ast.Call) {
51 // Look up the function in the map
52 function, ok := c.Scope.LookupFunc(n.Func)
54 c.createErr(n, fmt.Sprintf("unknown function called: %s", n.Func))
58 // Break up the args into what is variadic and what is required
60 if function.Variadic && len(args) > len(function.ArgTypes) {
61 args = n.Args[:len(function.ArgTypes)]
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)))
73 func (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))
82 func (c *IdentifierCheck) createErr(n ast.Node, str string) {
83 c.err = fmt.Errorf("%s: %s", n.Pos(), str)
86 func (c *IdentifierCheck) reset() {