github.com/keysonzzz/kmg@v0.0.0-20151121023212-05317bfd7d39/kmgRpc/kmgRpc.go (about) 1 package kmgRpc 2 3 import ( 4 "strings" 5 6 "github.com/bronze1man/kmg/kmgCache" 7 "github.com/bronze1man/kmg/kmgConfig" 8 "github.com/bronze1man/kmg/kmgFile" 9 "github.com/bronze1man/kmg/kmgGoSource/kmgFormat" 10 "path/filepath" 11 ) 12 13 type GenerateRequest struct { 14 //Object interface{} //需要分析的对象 15 ObjectPkgPath string //TODO 对此处进行封装,解决描述对象问题. 16 ObjectName string 17 ObjectIsPointer bool 18 OutFilePath string //生成的文件路径 19 OutPackageImportPath string //生成的package的importPath 20 ApiNameFilterCb func(name string) bool 21 } 22 23 //生成代码 24 // 会把Object上面所有的公开函数都拿去生成一遍 25 func MustGenerateCode(req *GenerateRequest) { 26 config := reflectToTplConfig(req) 27 outBs := tplGenerateCode(config) 28 outB := []byte(outBs) 29 outB1, err := kmgFormat.Source(outB) 30 if err == nil { 31 outB = outB1 32 } 33 kmgFile.MustWriteFileWithMkdir(req.OutFilePath, outB) 34 return 35 } 36 37 // 使用缓存 生成代码 38 func MustGenerateCodeWithCache(req *GenerateRequest) { 39 pkgFilePath := kmgConfig.DefaultEnv().PathInProject(filepath.Join("src", req.ObjectPkgPath)) 40 kmgCache.MustMd5FileChangeCache("kmgRpc_"+req.OutFilePath, []string{req.OutFilePath, pkgFilePath}, func() { 41 MustGenerateCode(req) 42 }) 43 } 44 45 type tplConfig struct { 46 OutPackageName string //生成的package的名字 testPackage 47 ObjectName string //对象名字 如 Demo 48 ObjectTypeStr string //对象的类型表示 如 *Demo 49 ImportPathMap map[string]bool //ImportPath列表 50 ApiList []Api //api列表 51 } 52 53 func (conf *tplConfig) mergeImportPath(importPathList []string) { 54 for _, importPath := range importPathList { 55 conf.ImportPathMap[importPath] = true 56 } 57 } 58 59 type Api struct { 60 Name string //在这个系统里面的名字 61 InArgsList []ArgumentNameTypePair //输入变量列表 62 OutArgsList []ArgumentNameTypePair //输出变量列表 63 } 64 65 func (api Api) GetOutArgsListWithoutError() []ArgumentNameTypePair { 66 out := make([]ArgumentNameTypePair, 0, len(api.OutArgsList)) 67 for _, pair := range api.OutArgsList { 68 if pair.ObjectTypeStr == "error" { 69 continue 70 } 71 out = append(out, pair) 72 } 73 return out 74 } 75 func (api Api) GetOutArgsNameListForAssign() string { 76 nameList := []string{} 77 for _, pair := range api.OutArgsList { 78 nameList = append(nameList, pair.Name) 79 } 80 return strings.Join(nameList, ",") 81 } 82 83 func (api Api) HasReturnArgument() bool { 84 return len(api.OutArgsList) > 0 85 } 86 87 func (api Api) GetClientOutArgument() []ArgumentNameTypePair { 88 // 确保客户端的接口的返回变量一定有一个error,用来返回错误. 89 for _, pair := range api.OutArgsList { 90 if pair.ObjectTypeStr == "error" { 91 return api.OutArgsList 92 } 93 } 94 return append(api.OutArgsList, ArgumentNameTypePair{ 95 Name: "Err", 96 ObjectTypeStr: "error", 97 }) 98 } 99 100 // TODO 下一个版本不要这个hook了,复杂度太高 101 func (api Api) IsOutExpendToOneArgument() bool { 102 return len(api.OutArgsList) == 2 && 103 api.OutArgsList[0].Name == "Response" && 104 api.OutArgsList[1].ObjectTypeStr == "error" 105 } 106 107 func (api Api) GetClientInArgsList() []ArgumentNameTypePair { 108 // 删去特殊输入参数 Ctx *http.Context 109 out := []ArgumentNameTypePair{} 110 for _, pair := range api.InArgsList { 111 if pair.ObjectTypeStr == "*kmgHttp.Context" { 112 continue 113 } 114 out = append(out, pair) 115 } 116 return out 117 } 118 119 func (api Api) HasHttpContextArgument() bool { 120 for _, pair := range api.InArgsList { 121 if pair.ObjectTypeStr == "*kmgHttp.Context" { 122 return true 123 } 124 } 125 return false 126 } 127 128 // 服务器端,函数调用的那个括号里面的东西 129 func (api Api) serverCallArgumentStr() string { 130 out := "" 131 for _, pair := range api.InArgsList { 132 if pair.ObjectTypeStr == "*kmgHttp.Context" { 133 out += "Ctx," 134 } else { 135 out += "reqData." + pair.Name + "," 136 } 137 } 138 return out 139 } 140 141 type ArgumentNameTypePair struct { 142 Name string 143 ObjectTypeStr string 144 }