github.com/keysonzzz/kmg@v0.0.0-20151121023212-05317bfd7d39/kmgGoSource/ReflectFuncDecl.go.bak (about) 1 package kmgGoSource 2 3 import ( 4 "fmt" 5 "reflect" 6 ) 7 8 //it is func decl with reflect func 9 //if a field not have a name 10 //only actual params ,not include recv 11 type ReflectFuncDecl struct { 12 Params []*ReflectFuncDeclField 13 Results []*ReflectFuncDeclField 14 ParamMap map[string]*ReflectFuncDeclField 15 ResultMap map[string]*ReflectFuncDeclField 16 ResultHasNames bool 17 } 18 19 type ReflectFuncDeclField struct { 20 Name string //may not have name 21 Type reflect.Type 22 Index int //place in origin param or result ,method include recv ,start from 0 23 } 24 25 //reflectType may not match funcDecl 26 func NewReflectFuncDecl(funcDecl *FuncDecl, rFunc reflect.Type, isMethod bool) (*ReflectFuncDecl, error) { 27 decl := &ReflectFuncDecl{ 28 ParamMap: make(map[string]*ReflectFuncDeclField), 29 ResultMap: make(map[string]*ReflectFuncDeclField), 30 } 31 paramIndex := 0 32 if isMethod { 33 paramIndex = 1 34 } 35 if len(funcDecl.ParamNames) != rFunc.NumIn()-paramIndex { 36 return nil, fmt.Errorf("NewReflectFuncDecl(): Param num not match FuncDecl: %d,reflectType: %d", 37 len(funcDecl.ParamNames), 38 rFunc.NumIn()-paramIndex, 39 ) 40 } 41 for _, name := range funcDecl.ParamNames { 42 field := &ReflectFuncDeclField{Name: name, Type: rFunc.In(paramIndex), Index: paramIndex} 43 decl.Params = append(decl.Params, field) 44 paramIndex++ 45 } 46 //result not have name 47 if len(funcDecl.ResultName) == 0 { 48 decl.ResultHasNames = false 49 for i := 0; i < rFunc.NumOut(); i++ { 50 decl.Results = append(decl.Results, &ReflectFuncDeclField{Type: rFunc.In(paramIndex), Index: i}) 51 } 52 } else { 53 decl.ResultHasNames = true 54 if len(funcDecl.ResultName) != rFunc.NumOut() { 55 return nil, fmt.Errorf("NewReflectFuncDecl(): Result num not match FuncDecl: %d,reflectType: %d", 56 len(funcDecl.ResultName), 57 rFunc.NumOut(), 58 ) 59 } 60 resultIndex := 0 61 //result have name 62 for _, name := range funcDecl.ResultName { 63 field := &ReflectFuncDeclField{Name: name, Type: rFunc.Out(resultIndex), Index: resultIndex} 64 decl.Results = append(decl.Results, field) 65 resultIndex++ 66 } 67 } 68 for _, field := range decl.Params { 69 decl.ParamMap[field.Name] = field 70 } 71 if decl.ResultHasNames { 72 for _, field := range decl.Results { 73 decl.ResultMap[field.Name] = field 74 } 75 } 76 return decl, nil 77 }