ast_router.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. package ast
  2. import (
  3. "bytes"
  4. "fmt"
  5. "go/ast"
  6. "go/parser"
  7. "go/printer"
  8. "go/token"
  9. "os"
  10. "strings"
  11. )
  12. func AppendNodeToList(stmts []ast.Stmt, stmt ast.Stmt, index int) []ast.Stmt {
  13. return append(stmts[:index], append([]ast.Stmt{stmt}, stmts[index:]...)...)
  14. }
  15. func AddRouterCode(path, funcName, pk, model string) {
  16. src, err := os.ReadFile(path)
  17. if err != nil {
  18. fmt.Println(err)
  19. }
  20. fileSet := token.NewFileSet()
  21. astFile, err := parser.ParseFile(fileSet, "", src, parser.ParseComments)
  22. if err != nil {
  23. fmt.Println(err)
  24. }
  25. FuncNode := FindFunction(astFile, funcName)
  26. pkName := strings.ToUpper(pk[:1]) + pk[1:]
  27. routerName := fmt.Sprintf("%sRouter", pk)
  28. modelName := fmt.Sprintf("Init%sRouter", model)
  29. var bloctPre *ast.BlockStmt
  30. for i := len(FuncNode.Body.List) - 1; i >= 0; i-- {
  31. if block, ok := FuncNode.Body.List[i].(*ast.BlockStmt); ok {
  32. bloctPre = block
  33. }
  34. }
  35. ast.Print(fileSet, FuncNode)
  36. if ok, b := needAppendRouter(FuncNode, pk); ok {
  37. routerNode :=
  38. &ast.BlockStmt{
  39. List: []ast.Stmt{
  40. &ast.AssignStmt{
  41. Lhs: []ast.Expr{
  42. &ast.Ident{Name: routerName},
  43. },
  44. Tok: token.DEFINE,
  45. Rhs: []ast.Expr{
  46. &ast.SelectorExpr{
  47. X: &ast.SelectorExpr{
  48. X: &ast.Ident{Name: "router"},
  49. Sel: &ast.Ident{Name: "RouterGroupApp"},
  50. },
  51. Sel: &ast.Ident{Name: pkName},
  52. },
  53. },
  54. },
  55. },
  56. }
  57. FuncNode.Body.List = AppendNodeToList(FuncNode.Body.List, routerNode, len(FuncNode.Body.List)-2)
  58. bloctPre = routerNode
  59. } else {
  60. bloctPre = b
  61. }
  62. if needAppendInit(FuncNode, routerName, modelName) {
  63. bloctPre.List = append(bloctPre.List,
  64. &ast.ExprStmt{
  65. X: &ast.CallExpr{
  66. Fun: &ast.SelectorExpr{
  67. X: &ast.Ident{Name: routerName},
  68. Sel: &ast.Ident{Name: modelName},
  69. },
  70. Args: []ast.Expr{
  71. &ast.Ident{
  72. Name: "PrivateGroup",
  73. },
  74. &ast.Ident{
  75. Name: "PublicGroup",
  76. },
  77. },
  78. },
  79. })
  80. }
  81. var out []byte
  82. bf := bytes.NewBuffer(out)
  83. printer.Fprint(bf, fileSet, astFile)
  84. os.WriteFile(path, bf.Bytes(), 0666)
  85. }
  86. func needAppendRouter(funcNode ast.Node, pk string) (bool, *ast.BlockStmt) {
  87. flag := true
  88. var block *ast.BlockStmt
  89. ast.Inspect(funcNode, func(node ast.Node) bool {
  90. switch n := node.(type) {
  91. case *ast.BlockStmt:
  92. for i := range n.List {
  93. if assignNode, ok := n.List[i].(*ast.AssignStmt); ok {
  94. if identNode, ok := assignNode.Lhs[0].(*ast.Ident); ok {
  95. if identNode.Name == fmt.Sprintf("%sRouter", pk) {
  96. flag = false
  97. block = n
  98. return false
  99. }
  100. }
  101. }
  102. }
  103. }
  104. return true
  105. })
  106. return flag, block
  107. }
  108. func needAppendInit(funcNode ast.Node, routerName string, modelName string) bool {
  109. flag := true
  110. ast.Inspect(funcNode, func(node ast.Node) bool {
  111. switch n := funcNode.(type) {
  112. case *ast.CallExpr:
  113. if selectNode, ok := n.Fun.(*ast.SelectorExpr); ok {
  114. x, xok := selectNode.X.(*ast.Ident)
  115. if xok && x.Name == routerName && selectNode.Sel.Name == modelName {
  116. flag = false
  117. return false
  118. }
  119. }
  120. }
  121. return true
  122. })
  123. return flag
  124. }