github.com/TheSpiritXIII/controller-tools@v0.14.1/pkg/loader/visit.go (about) 1 /* 2 Copyright 2019 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package loader 18 19 import ( 20 "go/ast" 21 "reflect" 22 "strconv" 23 ) 24 25 // TypeCallback is a callback called for each raw AST (gendecl, typespec) combo. 26 type TypeCallback func(file *ast.File, decl *ast.GenDecl, spec *ast.TypeSpec) 27 28 // EachType calls the given callback for each (gendecl, typespec) combo in the 29 // given package. Generally, using markers.EachType is better when working 30 // with marker data, and has a more convinient representation. 31 func EachType(pkg *Package, cb TypeCallback) { 32 visitor := &typeVisitor{ 33 callback: cb, 34 } 35 pkg.NeedSyntax() 36 for _, file := range pkg.Syntax { 37 visitor.file = file 38 ast.Walk(visitor, file) 39 } 40 } 41 42 // typeVisitor visits all TypeSpecs, calling the given callback for each. 43 type typeVisitor struct { 44 callback TypeCallback 45 decl *ast.GenDecl 46 file *ast.File 47 } 48 49 // Visit visits all TypeSpecs. 50 func (v *typeVisitor) Visit(node ast.Node) ast.Visitor { 51 if node == nil { 52 v.decl = nil 53 return v 54 } 55 56 switch typedNode := node.(type) { 57 case *ast.File: 58 v.file = typedNode 59 return v 60 case *ast.GenDecl: 61 v.decl = typedNode 62 return v 63 case *ast.TypeSpec: 64 v.callback(v.file, v.decl, typedNode) 65 return nil // don't recurse 66 default: 67 return nil 68 } 69 } 70 71 // ParseAstTag parses the given raw tag literal into a reflect.StructTag. 72 func ParseAstTag(tag *ast.BasicLit) reflect.StructTag { 73 if tag == nil { 74 return reflect.StructTag("") 75 } 76 tagStr, err := strconv.Unquote(tag.Value) 77 if err != nil { 78 return reflect.StructTag("") 79 } 80 return reflect.StructTag(tagStr) 81 }