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  }