parsesimplegofile.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. package utils
  2. import (
  3. "fmt"
  4. "go/ast"
  5. "go/parser"
  6. "go/token"
  7. "io/ioutil"
  8. "strings"
  9. "zero/tools/goctl/api/spec"
  10. )
  11. const (
  12. StructArr = "struct"
  13. ImportArr = "import"
  14. Unknown = "unknown"
  15. )
  16. type Struct struct {
  17. Name string
  18. Fields []spec.Member
  19. }
  20. func readFile(filePath string) (string, error) {
  21. b, err := ioutil.ReadFile(filePath)
  22. if err != nil {
  23. return "", err
  24. }
  25. return string(b), nil
  26. }
  27. func ParseNetworkGoFile(io string) ([]Struct, []string, error) {
  28. fset := token.NewFileSet() // 位置是相对于节点
  29. f, err := parser.ParseFile(fset, "", io, 0)
  30. if err != nil {
  31. return nil, nil, err
  32. }
  33. return parse(f)
  34. }
  35. func ParseGoFile(pathOrStr string) ([]Struct, []string, error) {
  36. var goFileStr string
  37. var err error
  38. goFileStr, err = readFile(pathOrStr)
  39. if err != nil {
  40. return nil, nil, err
  41. }
  42. fset := token.NewFileSet() // 位置是相对于节点
  43. f, err := parser.ParseFile(fset, "", goFileStr, 0)
  44. if err != nil {
  45. return nil, nil, err
  46. }
  47. return parse(f)
  48. }
  49. func ParseGoFileByNetwork(io string) ([]Struct, []string, error) {
  50. fset := token.NewFileSet() // 位置是相对于节点
  51. f, err := parser.ParseFile(fset, "", io, 0)
  52. if err != nil {
  53. return nil, nil, err
  54. }
  55. return parse(f)
  56. }
  57. //使用ast包解析golang文件
  58. func parse(f *ast.File) ([]Struct, []string, error) {
  59. if len(f.Decls) == 0 {
  60. return nil, nil, fmt.Errorf("you should provide as least 1 struct")
  61. }
  62. var structList []Struct
  63. var importList []string
  64. for _, decl := range f.Decls {
  65. structs, imports, err := getStructAndImportInfo(decl)
  66. if err != nil {
  67. return nil, nil, err
  68. }
  69. structList = append(structList, structs...)
  70. importList = append(importList, imports...)
  71. }
  72. return structList, importList, nil
  73. }
  74. func getStructAndImportInfo(decl ast.Decl) (structs []Struct, imports []string, err error) {
  75. var structList []Struct
  76. var importList []string
  77. genDecl, ok := decl.(*ast.GenDecl)
  78. if !ok {
  79. return nil, nil, fmt.Errorf("please input right file")
  80. }
  81. for _, tpyObj := range genDecl.Specs {
  82. switch tpyObj.(type) {
  83. case *ast.ImportSpec: // import
  84. importSpec := tpyObj.(*ast.ImportSpec)
  85. s := importSpec.Path.Value
  86. importList = append(importList, s)
  87. case *ast.TypeSpec: //type
  88. typeSpec := tpyObj.(*ast.TypeSpec)
  89. switch typeSpec.Type.(type) {
  90. case *ast.StructType: // struct
  91. struct1, err := parseStruct(typeSpec)
  92. if err != nil {
  93. return nil, nil, err
  94. }
  95. structList = append(structList, *struct1)
  96. }
  97. default:
  98. }
  99. }
  100. return structList, importList, nil
  101. }
  102. func parseStruct(typeSpec *ast.TypeSpec) (*Struct, error) {
  103. var result Struct
  104. structName := typeSpec.Name.Name
  105. result.Name = structName
  106. structType, ok := typeSpec.Type.(*ast.StructType)
  107. if !ok {
  108. return nil, fmt.Errorf("not struct")
  109. }
  110. for _, item := range structType.Fields.List {
  111. var member spec.Member
  112. var err error
  113. member.Name = parseFiledName(item.Names)
  114. member.Type, err = parseFiledType(item.Type)
  115. if err != nil {
  116. return nil, err
  117. }
  118. if item.Tag != nil {
  119. member.Tag = item.Tag.Value
  120. }
  121. result.Fields = append(result.Fields, member)
  122. }
  123. return &result, nil
  124. }
  125. func parseFiledType(expr ast.Expr) (string, error) {
  126. switch expr.(type) {
  127. case *ast.Ident:
  128. return expr.(*ast.Ident).Name, nil
  129. case *ast.SelectorExpr:
  130. selectorExpr := expr.(*ast.SelectorExpr)
  131. return selectorExpr.X.(*ast.Ident).Name + "." + selectorExpr.Sel.Name, nil
  132. default:
  133. return "", fmt.Errorf("can't parse type")
  134. }
  135. }
  136. func parseFiledName(idents []*ast.Ident) string {
  137. for _, name := range idents {
  138. return name.Name
  139. }
  140. return ""
  141. }
  142. func UpperCamelToLower(name string) string {
  143. if len(name) == 0 {
  144. return ""
  145. }
  146. return strings.ToLower(name[:1]) + name[1:]
  147. }