github.com/keysonzzz/kmg@v0.0.0-20151121023212-05317bfd7d39/kmgGoSource/kmgReflectV2.go (about) 1 package kmgGoSource 2 3 import ( 4 "fmt" 5 "go/doc" 6 "reflect" 7 ) 8 9 type Kind string 10 11 const ( 12 Struct Kind = "Struct" 13 Ptr Kind = "Ptr" 14 ) 15 16 //表示一个指针类型 17 type TypePointer struct { 18 Elem Type 19 } 20 21 func (p TypePointer) Kind() Kind { 22 return Ptr 23 } 24 func (p TypePointer) Method() []Method { 25 return p.Elem.Method() 26 } 27 func (p TypePointer) WriteInPkgPath(currentPkgPath string) (str string, importPathList []string) { 28 str, importPathList = p.Elem.WriteInPkgPath(currentPkgPath) 29 return "*" + str, importPathList 30 } 31 32 //表示一个struct类型 33 type TypeStruct struct { 34 docType *doc.Type 35 pkg *Package 36 reflectType reflect.Type 37 } 38 39 func (p TypeStruct) Kind() Kind { 40 return Struct 41 } 42 func (p TypeStruct) Package() *Package { 43 return p.pkg 44 } 45 func (p TypeStruct) Method() []Method { 46 numMethod := p.reflectType.NumMethod() 47 if numMethod == 0 { 48 return nil 49 } 50 out := make([]Method, numMethod) 51 for i := 0; i < numMethod; i++ { 52 refletMethod := p.reflectType.Method(i) 53 method := Method{ 54 Recv: p, 55 Func: Func{ 56 Name: refletMethod.Name, 57 }, 58 } 59 60 out[i] = method 61 } 62 return out 63 } 64 65 func (p TypeStruct) WriteInPkgPath(currentPkgPath string) (str string, importPathList []string) { 66 thisPkgPath := p.Package().PkgPath() 67 if thisPkgPath == "" || currentPkgPath == thisPkgPath { 68 return p.docType.Name, nil 69 } 70 return p.Package().Name() + "." + p.docType.Name, []string{thisPkgPath} 71 } 72 73 //表示一种golang的类型 74 type Type interface { 75 Kind() Kind 76 Method() []Method 77 //在这个pkgPath里面的表示方法 78 WriteInPkgPath(currentPkgPath string) (str string, importPathList []string) 79 } 80 81 type Method struct { 82 Recv Type 83 Func 84 } 85 86 type Func struct { 87 Name string 88 InArgList []FuncArgument 89 OutArgList []FuncArgument 90 } 91 92 type FuncArgument struct { 93 Name string 94 Type Type 95 } 96 97 //从反射的类型获取一个Type 98 // 主要: 需要运行时有源代码,需要使用kmg配置GOPATH 99 func MustNewTypeFromReflectType(typ reflect.Type) Type { 100 switch typ.Kind() { 101 case reflect.Ptr: 102 return TypePointer{ 103 Elem: MustNewTypeFromReflectType(typ.Elem()), 104 } 105 case reflect.Struct: 106 pkgPath := typ.PkgPath() 107 if pkgPath == "" { 108 panic(`TODO Handle pkgPath==""`) 109 } 110 pkg := MustNewPackageFromImportPath(pkgPath) 111 docType := pkg.getDocTypeByName(typ.Name()) 112 return TypeStruct{ 113 docType: docType, 114 pkg: pkg, 115 reflectType: typ, 116 } 117 default: 118 panic(fmt.Errorf("not process kind:%s", typ.Kind())) 119 } 120 121 }