github.com/unionj-cloud/go-doudou@v1.3.8-0.20221011095552-0088008e5b31/cmd/internal/svc/codegen/ast.go (about)

     1  package codegen
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"github.com/unionj-cloud/go-doudou/cmd/internal/astutils"
     7  	"go/ast"
     8  	"strings"
     9  )
    10  
    11  // ExprStringP Support all built-in type referenced from https://golang.org/pkg/builtin/
    12  // Support map with string key
    13  // Support structs of vo package
    14  // Support slice of types mentioned above
    15  // Not support alias type (all alias type fields of a struct will be outputted as v3.Any in openapi 3.0 json document)
    16  // Support anonymous struct type
    17  // as struct field type in vo package
    18  // or as parameter type in method signature in svc.go file besides context.Context, multipart.FileHeader, v3.FileModel, os.File
    19  // when go-doudou command line flag doc is true
    20  func ExprStringP(expr ast.Expr) string {
    21  	switch _expr := expr.(type) {
    22  	case *ast.Ident:
    23  		return _expr.Name
    24  	case *ast.StarExpr:
    25  		return "*" + ExprStringP(_expr.X)
    26  	case *ast.SelectorExpr:
    27  		return parseSelectorExpr(_expr)
    28  	case *ast.InterfaceType:
    29  		return "interface{}"
    30  	case *ast.ArrayType:
    31  		if _expr.Len == nil {
    32  			return "[]" + ExprStringP(_expr.Elt)
    33  		}
    34  		return "[" + ExprStringP(_expr.Len) + "]" + ExprStringP(_expr.Elt)
    35  	case *ast.BasicLit:
    36  		return _expr.Value
    37  	case *ast.MapType:
    38  		if ExprStringP(_expr.Key) != "string" {
    39  			panic("support string map key only in svc.go file and vo package")
    40  		}
    41  		return "map[string]" + ExprStringP(_expr.Value)
    42  	case *ast.StructType:
    43  		structmeta := astutils.NewStructMeta(_expr, ExprStringP)
    44  		b, _ := json.Marshal(structmeta)
    45  		return "anonystruct«" + string(b) + "»"
    46  	case *ast.Ellipsis:
    47  		if _expr.Ellipsis.IsValid() {
    48  			return "..." + ExprStringP(_expr.Elt)
    49  		}
    50  		panic(fmt.Sprintf("invalid ellipsis expression: %+v\n", expr))
    51  	case *ast.FuncType:
    52  		panic("not support function as struct field type in vo package and as parameter in method signature in svc.go file")
    53  	case *ast.ChanType:
    54  		panic("not support channel as struct field type in vo package and as parameter in method signature in svc.go file")
    55  	default:
    56  		panic(fmt.Errorf("not support expression as struct field type in vo package and in method signature in svc.go file: %+v", expr))
    57  	}
    58  }
    59  
    60  func parseSelectorExpr(expr *ast.SelectorExpr) string {
    61  	result := ExprStringP(expr.X) + "." + expr.Sel.Name
    62  	if !strings.HasPrefix(result, "vo.") &&
    63  		result != "context.Context" &&
    64  		result != "v3.FileModel" &&
    65  		result != "multipart.FileHeader" &&
    66  		result != "os.File" {
    67  		panic(fmt.Errorf("not support %s in svc.go file and vo package", result))
    68  	}
    69  	return result
    70  }