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  }