github.com/hashicorp/hcl/v2@v2.20.0/hclsyntax/expression_vars_gen.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 // This is a 'go generate'-oriented program for producing the "Variables" 5 // method on every Expression implementation found within this package. 6 // All expressions share the same implementation for this method, which 7 // just wraps the package-level function "Variables" and uses an AST walk 8 // to do its work. 9 10 //go:build ignore 11 // +build ignore 12 13 package main 14 15 import ( 16 "fmt" 17 "go/ast" 18 "go/parser" 19 "go/token" 20 "os" 21 "sort" 22 ) 23 24 func main() { 25 fs := token.NewFileSet() 26 pkgs, err := parser.ParseDir(fs, ".", nil, 0) 27 if err != nil { 28 fmt.Fprintf(os.Stderr, "error while parsing: %s\n", err) 29 os.Exit(1) 30 } 31 pkg := pkgs["hclsyntax"] 32 33 // Walk all the files and collect the receivers of any "Value" methods 34 // that look like they are trying to implement Expression. 35 var recvs []string 36 for _, f := range pkg.Files { 37 for _, decl := range f.Decls { 38 fd, ok := decl.(*ast.FuncDecl) 39 if !ok { 40 continue 41 } 42 if fd.Name.Name != "Value" { 43 continue 44 } 45 results := fd.Type.Results.List 46 if len(results) != 2 { 47 continue 48 } 49 valResult := fd.Type.Results.List[0].Type.(*ast.SelectorExpr).X.(*ast.Ident) 50 diagsResult := fd.Type.Results.List[1].Type.(*ast.SelectorExpr).X.(*ast.Ident) 51 52 if valResult.Name != "cty" && diagsResult.Name != "hcl" { 53 continue 54 } 55 56 // If we have a method called Value and it returns something in 57 // "cty" followed by something in "hcl" then that's specific enough 58 // for now, even though this is not 100% exact as a correct 59 // implementation of Value. 60 61 recvTy := fd.Recv.List[0].Type 62 63 switch rtt := recvTy.(type) { 64 case *ast.StarExpr: 65 name := rtt.X.(*ast.Ident).Name 66 recvs = append(recvs, fmt.Sprintf("*%s", name)) 67 default: 68 fmt.Fprintf(os.Stderr, "don't know what to do with a %T receiver\n", recvTy) 69 } 70 71 } 72 } 73 74 sort.Strings(recvs) 75 76 of, err := os.OpenFile("expression_vars.go", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.ModePerm) 77 if err != nil { 78 fmt.Fprintf(os.Stderr, "failed to open output file: %s\n", err) 79 os.Exit(1) 80 } 81 82 fmt.Fprint(of, outputPreamble) 83 for _, recv := range recvs { 84 fmt.Fprintf(of, outputMethodFmt, recv) 85 } 86 fmt.Fprint(of, "\n") 87 88 } 89 90 const outputPreamble = `// Copyright (c) HashiCorp, Inc. 91 // SPDX-License-Identifier: MPL-2.0 92 93 package hclsyntax 94 95 // Generated by expression_vars_get.go. DO NOT EDIT. 96 // Run 'go generate' on this package to update the set of functions here. 97 98 import ( 99 "github.com/hashicorp/hcl/v2" 100 )` 101 102 const outputMethodFmt = ` 103 104 func (e %s) Variables() []hcl.Traversal { 105 return Variables(e) 106 }`