123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- package utils
- import (
- "fmt"
- "go/ast"
- "go/parser"
- "go/token"
- "io/ioutil"
- "strings"
- "zero/tools/goctl/api/spec"
- )
- const (
- StructArr = "struct"
- ImportArr = "import"
- Unknown = "unknown"
- )
- type Struct struct {
- Name string
- Fields []spec.Member
- }
- func readFile(filePath string) (string, error) {
- b, err := ioutil.ReadFile(filePath)
- if err != nil {
- return "", err
- }
- return string(b), nil
- }
- func ParseNetworkGoFile(io string) ([]Struct, []string, error) {
- fset := token.NewFileSet() // 位置是相对于节点
- f, err := parser.ParseFile(fset, "", io, 0)
- if err != nil {
- return nil, nil, err
- }
- return parse(f)
- }
- func ParseGoFile(pathOrStr string) ([]Struct, []string, error) {
- var goFileStr string
- var err error
- goFileStr, err = readFile(pathOrStr)
- if err != nil {
- return nil, nil, err
- }
- fset := token.NewFileSet() // 位置是相对于节点
- f, err := parser.ParseFile(fset, "", goFileStr, 0)
- if err != nil {
- return nil, nil, err
- }
- return parse(f)
- }
- func ParseGoFileByNetwork(io string) ([]Struct, []string, error) {
- fset := token.NewFileSet() // 位置是相对于节点
- f, err := parser.ParseFile(fset, "", io, 0)
- if err != nil {
- return nil, nil, err
- }
- return parse(f)
- }
- //使用ast包解析golang文件
- func parse(f *ast.File) ([]Struct, []string, error) {
- if len(f.Decls) == 0 {
- return nil, nil, fmt.Errorf("you should provide as least 1 struct")
- }
- var structList []Struct
- var importList []string
- for _, decl := range f.Decls {
- structs, imports, err := getStructAndImportInfo(decl)
- if err != nil {
- return nil, nil, err
- }
- structList = append(structList, structs...)
- importList = append(importList, imports...)
- }
- return structList, importList, nil
- }
- func getStructAndImportInfo(decl ast.Decl) (structs []Struct, imports []string, err error) {
- var structList []Struct
- var importList []string
- genDecl, ok := decl.(*ast.GenDecl)
- if !ok {
- return nil, nil, fmt.Errorf("please input right file")
- }
- for _, tpyObj := range genDecl.Specs {
- switch tpyObj.(type) {
- case *ast.ImportSpec: // import
- importSpec := tpyObj.(*ast.ImportSpec)
- s := importSpec.Path.Value
- importList = append(importList, s)
- case *ast.TypeSpec: //type
- typeSpec := tpyObj.(*ast.TypeSpec)
- switch typeSpec.Type.(type) {
- case *ast.StructType: // struct
- struct1, err := parseStruct(typeSpec)
- if err != nil {
- return nil, nil, err
- }
- structList = append(structList, *struct1)
- }
- default:
- }
- }
- return structList, importList, nil
- }
- func parseStruct(typeSpec *ast.TypeSpec) (*Struct, error) {
- var result Struct
- structName := typeSpec.Name.Name
- result.Name = structName
- structType, ok := typeSpec.Type.(*ast.StructType)
- if !ok {
- return nil, fmt.Errorf("not struct")
- }
- for _, item := range structType.Fields.List {
- var member spec.Member
- var err error
- member.Name = parseFiledName(item.Names)
- member.Type, err = parseFiledType(item.Type)
- if err != nil {
- return nil, err
- }
- if item.Tag != nil {
- member.Tag = item.Tag.Value
- }
- result.Fields = append(result.Fields, member)
- }
- return &result, nil
- }
- func parseFiledType(expr ast.Expr) (string, error) {
- switch expr.(type) {
- case *ast.Ident:
- return expr.(*ast.Ident).Name, nil
- case *ast.SelectorExpr:
- selectorExpr := expr.(*ast.SelectorExpr)
- return selectorExpr.X.(*ast.Ident).Name + "." + selectorExpr.Sel.Name, nil
- default:
- return "", fmt.Errorf("can't parse type")
- }
- }
- func parseFiledName(idents []*ast.Ident) string {
- for _, name := range idents {
- return name.Name
- }
- return ""
- }
- func UpperCamelToLower(name string) string {
- if len(name) == 0 {
- return ""
- }
- return strings.ToLower(name[:1]) + name[1:]
- }
|