github.com/keysonZZZ/kmg@v0.0.0-20151121023212-05317bfd7d39/kmgRpc/kmgRpcSwift/reflect.go (about) 1 package kmgRpcSwift 2 3 import ( 4 "fmt" 5 6 "github.com/bronze1man/kmg/kmgGoSource/kmgGoParser" 7 "github.com/bronze1man/kmg/kmgStrings" 8 "log" 9 "strconv" 10 ) 11 12 func reflectToTplConfig(req *GenerateRequest) *tplConfig { 13 config := &tplConfig{ 14 ClassName: req.OutClassName, 15 innerClassMap: map[string]*InnerClass{}, 16 } 17 if req.ApiNameFilterCb == nil { 18 req.ApiNameFilterCb = func(name string) bool { 19 return true 20 } 21 } 22 23 pkg := kmgGoParser.NewProgramFromDefault().GetPackage(req.ObjectPkgPath) 24 namedTyp := pkg.LookupNamedType(req.ObjectName) 25 if namedTyp == nil { 26 panic(fmt.Errorf("can not find this object. [%s]", req.ObjectName)) 27 } 28 objTyp := kmgGoParser.Type(namedTyp) 29 if req.ObjectIsPointer { 30 objTyp = kmgGoParser.NewPointer(objTyp) 31 } 32 //获取 object 上面所有的方法 33 methodList := pkg.GetNamedTypeMethodSet(namedTyp) 34 for _, methodObj := range methodList { 35 log.Println(methodObj.Name) 36 log.Println(methodObj.OutParameter) 37 log.Println(methodObj.InParameter) 38 log.Println(methodObj.ReceiverType.GetKind()) 39 if !methodObj.IsExport() { 40 continue 41 } 42 if !req.ApiNameFilterCb(methodObj.Name) { 43 continue 44 } 45 api := Api{ 46 Name: methodObj.Name, 47 } 48 RequestInnerClass := &InnerClass{ 49 Name: api.Name + "RpcRequest", 50 IsPublic: false, 51 } 52 for _, pairObj := range methodObj.InParameter { 53 pair := NameTypePair{ 54 Name: kmgStrings.FirstLetterToUpper(pairObj.Name), 55 } 56 pair.TypeStr = config.addType(pairObj.Type) 57 api.InArgsList = append(api.InArgsList, pair) 58 RequestInnerClass.FieldList = append(RequestInnerClass.FieldList, pair) 59 } 60 config.addInnerClass(RequestInnerClass) 61 /* 62 * 在java中,如果输出参数的类型是error,会转到exception里面 63 * 在java中,如果输出参数去除error后,没有参数了,java函数不会返回参数 64 * 在java中,如果输出参数除去error后,还有1个,直接返回这个类型,此时此参数依然按照前面的说法进行向前兼容. 65 * 在java中,如果输出参数除去error后,还有2个及2个以上,返回一个class,这个class包含这些个参数. 66 */ 67 notErrorOutParameter := []NameTypePair{} 68 for i, pairObj := range methodObj.OutParameter { 69 builtintyp, ok := pairObj.Type.(kmgGoParser.BuiltinType) 70 if !(ok && string(builtintyp) == "error") { 71 name := kmgStrings.FirstLetterToUpper(pairObj.Name) 72 if name == "" { 73 name = "Out_" + strconv.Itoa(i) 74 } 75 notErrorOutParameter = append(notErrorOutParameter, NameTypePair{ 76 Name: name, 77 TypeStr: config.addType(pairObj.Type), 78 }) 79 } 80 } 81 if len(notErrorOutParameter) == 0 { 82 api.OutTypeString = "void" 83 } else { 84 responseInnerClass := &InnerClass{ 85 Name: api.Name + "RpcResponse", 86 FieldList: notErrorOutParameter, 87 IsPublic: false, 88 } 89 config.addInnerClass(responseInnerClass) 90 91 if len(notErrorOutParameter) == 1 { 92 api.OutTypeString = notErrorOutParameter[0].TypeStr 93 api.OutTypeFieldName = notErrorOutParameter[0].Name 94 } else { 95 api.OutTypeString = responseInnerClass.Name 96 } 97 } 98 config.ApiList = append(config.ApiList, api) 99 } 100 return config 101 } 102 103 func (config *tplConfig) addType(typi kmgGoParser.Type) string { 104 switch typ := typi.(type) { 105 //case kmgGoParser.FuncType: 106 // panic("TODO") 107 case kmgGoParser.PointerType: 108 return config.addType(typ.Elem) 109 case *kmgGoParser.NamedType: 110 if typ.Name == "Time" && typ.PackagePath == "time" { 111 return "NSDate" 112 } 113 name := typ.Name 114 ntyp := config.innerClassMap[name] 115 if ntyp != nil { 116 return name 117 } 118 switch utyp := typ.GetUnderType().(type) { 119 case kmgGoParser.StructType: 120 innerClass := &InnerClass{ 121 Name: name, 122 IsPublic: true, 123 } 124 config.addInnerClass(innerClass) // 避免循环引用导致出现bug. 125 for i := range utyp.Field { 126 innerClass.FieldList = append(innerClass.FieldList, NameTypePair{ 127 Name: utyp.Field[i].Name, 128 TypeStr: config.addType(utyp.Field[i].Elem), 129 }) 130 } 131 return name 132 default: 133 return config.addType(utyp) 134 } 135 case kmgGoParser.BuiltinType: 136 s, ok := builtinTypeMap[string(typ)] 137 if !ok { 138 panic("not support BuiltinType " + string(typ)) 139 } 140 return s 141 case kmgGoParser.SliceType: 142 return "[" + config.addType(typ.Elem) + "]" 143 default: 144 panic(fmt.Errorf("TODO %T", typi)) 145 } 146 } 147 148 var builtinTypeMap = map[string]string{ 149 "string": "NSString", 150 "int": "Int", 151 "int64": "Int", 152 "float64": "Float", 153 "bool": "Bool", 154 "byte": "UInt8", 155 }