github.com/nyan233/littlerpc@v0.4.6-0.20230316182519-0c8d5c48abaf/cmd/pxtor/utils.go (about) 1 package main 2 3 import ( 4 "errors" 5 "fmt" 6 "go/ast" 7 "os" 8 "strings" 9 ) 10 11 func handleAstType(expr ast.Expr, file *os.File) string { 12 switch expr.(type) { 13 case *ast.MapType: 14 typ := expr.(*ast.MapType) 15 pos := fileSet.Position(typ.Pos()) 16 buf := []byte{0} 17 _, err := file.ReadAt(buf, int64(pos.Offset)) 18 if err != nil { 19 panic(interface{}(err)) 20 } 21 if buf[0] == '*' { 22 return "*map[" + handleAstType(typ.Key, file) + "]" + handleAstType(typ.Value, file) 23 } 24 return "map[" + handleAstType(typ.Key, file) + "]" + handleAstType(typ.Value, file) 25 case *ast.Ident: 26 ident := expr.(*ast.Ident) 27 pos := fileSet.Position(ident.Pos()) 28 buf := []byte{0} 29 _, err := file.ReadAt(buf, int64(pos.Offset)) 30 if err != nil { 31 panic(interface{}(err)) 32 } 33 if buf[0] == '*' { 34 return "*" + ident.Name 35 } 36 return ident.Name 37 case *ast.StarExpr: 38 s := expr.(*ast.StarExpr) 39 pos := fileSet.Position(s.Pos()) 40 buf := []byte{0} 41 _, err := file.ReadAt(buf, int64(pos.Offset)) 42 if err != nil { 43 panic(interface{}(err)) 44 } 45 if buf[0] == '*' { 46 return "*" + handleAstType(s.X, file) 47 } 48 return handleAstType(s.X, file) 49 case *ast.ArrayType: 50 at := expr.(*ast.ArrayType) 51 pos := fileSet.Position(at.Pos()) 52 buf := []byte{0} 53 _, err := file.ReadAt(buf, int64(pos.Offset)) 54 if err != nil { 55 panic(interface{}(err)) 56 } 57 if buf[0] == '*' { 58 return "*[]" + handleAstType(at.Elt, file) 59 } 60 return "[]" + handleAstType(at.Elt, file) 61 case *ast.SelectorExpr: 62 se := expr.(*ast.SelectorExpr) 63 return handleAstType(se.X, file) + "." + handleAstType(se.Sel, file) 64 default: 65 panic(interface{}("type is no supported")) 66 } 67 } 68 69 func writeDefaultValue(str string) (string, error) { 70 // 切片和指针类型直接返回nil 71 if str[0] == '*' || (str[0] == '[' && str[1] == ']') { 72 return "nil", nil 73 } 74 switch str { 75 case "int8", "int16", "uint16": 76 return "", errors.New("no support type") 77 case "uint8", "byte", "int32", "int64", "uint32", "uint64", "int": 78 return "0", nil 79 case "string": 80 return `""`, nil 81 case "bool": 82 return "false", nil 83 default: 84 // littlerpc不支持chan类型的参数 85 if str[:4] == "chan" { 86 return "", errors.New("no support type") 87 } 88 // map类型也返回nil 89 if str[:3] == "map" { 90 return "nil", nil 91 } 92 // 是数组并非是切片 93 if str[0] == '[' && str[1] != ']' { 94 return str + "{}", nil 95 } 96 // 默认被设定为struct类型 97 return str + "{}", nil 98 } 99 } 100 101 // 根据方法集生成对应的接口 102 // Example : type dd interface {Say();Sel();} 103 func createInterface(typeName string, methods []string) string { 104 var sb strings.Builder 105 _, _ = fmt.Fprintf(&sb, "type %s interface {", typeName) 106 for _, method := range methods { 107 sb.WriteString(method) 108 sb.WriteString(";") 109 } 110 return sb.String() 111 }