parser.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. package main
  2. import (
  3. "fmt"
  4. "go/ast"
  5. "go/parser"
  6. "go/token"
  7. "io/ioutil"
  8. "os"
  9. "strings"
  10. )
  11. type param struct{ K, V, P string }
  12. type parse struct {
  13. Path string
  14. Package string
  15. Imports []string
  16. Funcs []*struct {
  17. Name string
  18. Method, Params, Result []*param
  19. }
  20. }
  21. func parseArgs(args []string, res *[]string, index int) (err error) {
  22. if len(args) <= index {
  23. return
  24. }
  25. if strings.HasPrefix(args[index], "-") {
  26. index += 2
  27. parseArgs(args, res, index)
  28. return
  29. }
  30. var f os.FileInfo
  31. if f, err = os.Stat(args[index]); err != nil {
  32. return
  33. }
  34. if f.IsDir() {
  35. if !strings.HasSuffix(args[index], "/") {
  36. args[index] += "/"
  37. }
  38. var fs []os.FileInfo
  39. if fs, err = ioutil.ReadDir(args[index]); err != nil {
  40. return
  41. }
  42. for _, f = range fs {
  43. args = append(args, args[index]+f.Name())
  44. }
  45. } else {
  46. if strings.HasSuffix(args[index], ".go") &&
  47. !strings.HasSuffix(args[index], "_test.go") {
  48. *res = append(*res, args[index])
  49. }
  50. }
  51. index++
  52. return parseArgs(args, res, index)
  53. }
  54. func parseFile(files ...string) (parses []*parse, err error) {
  55. for _, file := range files {
  56. var (
  57. astFile *ast.File
  58. fSet = token.NewFileSet()
  59. parse = &parse{}
  60. )
  61. if astFile, err = parser.ParseFile(fSet, file, nil, 0); err != nil {
  62. return
  63. }
  64. if astFile.Name != nil {
  65. parse.Path = file
  66. parse.Package = astFile.Name.Name
  67. }
  68. for _, decl := range astFile.Decls {
  69. switch decl.(type) {
  70. case *ast.GenDecl:
  71. for _, spec := range decl.(*ast.GenDecl).Specs {
  72. switch spec.(type) {
  73. case *ast.ImportSpec:
  74. parse.Imports = append(parse.Imports, spec.(*ast.ImportSpec).Path.Value)
  75. }
  76. }
  77. case *ast.FuncDecl:
  78. var (
  79. dec = decl.(*ast.FuncDecl)
  80. parseFunc = &struct {
  81. Name string
  82. Method, Params, Result []*param
  83. }{Name: dec.Name.Name}
  84. )
  85. if dec.Recv != nil {
  86. parseFunc.Method = parserParams(dec.Recv.List)
  87. }
  88. if dec.Type.Params != nil {
  89. parseFunc.Params = parserParams(dec.Type.Params.List)
  90. }
  91. if dec.Type.Results != nil {
  92. parseFunc.Result = parserParams(dec.Type.Results.List)
  93. }
  94. parse.Funcs = append(parse.Funcs, parseFunc)
  95. }
  96. }
  97. parses = append(parses, parse)
  98. }
  99. return
  100. }
  101. func parserParams(fields []*ast.Field) (params []*param) {
  102. for _, field := range fields {
  103. p := &param{}
  104. //TODO:调用parseType解析类型
  105. p.V = parseType(field.Type)
  106. if field.Names == nil {
  107. params = append(params, p)
  108. }
  109. for _, name := range field.Names {
  110. sp := &param{}
  111. sp.K = name.Name
  112. if sp.K == "t" {
  113. sp.K = "no"
  114. }
  115. sp.V = p.V
  116. sp.P = p.P
  117. params = append(params, sp)
  118. }
  119. }
  120. return
  121. }
  122. func parseType(expr ast.Expr) string {
  123. switch expr.(type) {
  124. case *ast.Ident:
  125. return expr.(*ast.Ident).Name
  126. case *ast.StarExpr:
  127. return "*" + parseType(expr.(*ast.StarExpr).X)
  128. case *ast.ArrayType:
  129. return "[" + parseType(expr.(*ast.ArrayType).Len) + "]" + parseType(expr.(*ast.ArrayType).Elt)
  130. case *ast.SelectorExpr:
  131. return parseType(expr.(*ast.SelectorExpr).X) + "." + expr.(*ast.SelectorExpr).Sel.Name
  132. case *ast.MapType:
  133. return "map[" + parseType(expr.(*ast.MapType).Key) + "]" + parseType(expr.(*ast.MapType).Value)
  134. case *ast.StructType:
  135. return "struct{}"
  136. case *ast.InterfaceType:
  137. return "interface{}"
  138. case *ast.FuncType:
  139. var (
  140. pTemp string
  141. rTemp string
  142. )
  143. pTemp = parseFuncType(pTemp, expr.(*ast.FuncType).Params)
  144. if expr.(*ast.FuncType).Results != nil {
  145. rTemp = parseFuncType(rTemp, expr.(*ast.FuncType).Results)
  146. return fmt.Sprintf("func(%s) (%s)", pTemp, rTemp)
  147. }
  148. return fmt.Sprintf("func(%s)", pTemp)
  149. case *ast.ChanType:
  150. return fmt.Sprintf("make(chan %s)", parseType(expr.(*ast.ChanType).Value))
  151. case *ast.Ellipsis:
  152. return parseType(expr.(*ast.Ellipsis).Elt)
  153. }
  154. return ""
  155. }
  156. func parseFuncType(temp string, data *ast.FieldList) string {
  157. var params = parserParams(data.List)
  158. for i, param := range params {
  159. if i == 0 {
  160. temp = param.K + " " + param.V
  161. continue
  162. }
  163. t := param.K + " " + param.V
  164. temp = fmt.Sprintf("%s, %s", temp, t)
  165. }
  166. return temp
  167. }