ast.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. package ast
  2. import (
  3. "fmt"
  4. "github.com/flipped-aurora/gin-vue-admin/server/model/system"
  5. "go/ast"
  6. "go/parser"
  7. "go/token"
  8. "log"
  9. )
  10. // AddImport 增加 import 方法
  11. func AddImport(astNode ast.Node, imp string) {
  12. impStr := fmt.Sprintf("\"%s\"", imp)
  13. ast.Inspect(astNode, func(node ast.Node) bool {
  14. if genDecl, ok := node.(*ast.GenDecl); ok {
  15. if genDecl.Tok == token.IMPORT {
  16. for i := range genDecl.Specs {
  17. if impNode, ok := genDecl.Specs[i].(*ast.ImportSpec); ok {
  18. if impNode.Path.Value == impStr {
  19. return false
  20. }
  21. }
  22. }
  23. genDecl.Specs = append(genDecl.Specs, &ast.ImportSpec{
  24. Path: &ast.BasicLit{
  25. Kind: token.STRING,
  26. Value: impStr,
  27. },
  28. })
  29. }
  30. }
  31. return true
  32. })
  33. }
  34. // FindFunction 查询特定function方法
  35. func FindFunction(astNode ast.Node, FunctionName string) *ast.FuncDecl {
  36. var funcDeclP *ast.FuncDecl
  37. ast.Inspect(astNode, func(node ast.Node) bool {
  38. if funcDecl, ok := node.(*ast.FuncDecl); ok {
  39. if funcDecl.Name.String() == FunctionName {
  40. funcDeclP = funcDecl
  41. return false
  42. }
  43. }
  44. return true
  45. })
  46. return funcDeclP
  47. }
  48. // FindArray 查询特定数组方法
  49. func FindArray(astNode ast.Node, identName, selectorExprName string) *ast.CompositeLit {
  50. var assignStmt *ast.CompositeLit
  51. ast.Inspect(astNode, func(n ast.Node) bool {
  52. switch node := n.(type) {
  53. case *ast.AssignStmt:
  54. for _, expr := range node.Rhs {
  55. if exprType, ok := expr.(*ast.CompositeLit); ok {
  56. if arrayType, ok := exprType.Type.(*ast.ArrayType); ok {
  57. sel, ok1 := arrayType.Elt.(*ast.SelectorExpr)
  58. x, ok2 := sel.X.(*ast.Ident)
  59. if ok1 && ok2 && x.Name == identName && sel.Sel.Name == selectorExprName {
  60. assignStmt = exprType
  61. return false
  62. }
  63. }
  64. }
  65. }
  66. }
  67. return true
  68. })
  69. return assignStmt
  70. }
  71. func CreateMenuStructAst(menus []system.SysBaseMenu) *[]ast.Expr {
  72. var menuElts []ast.Expr
  73. for i := range menus {
  74. elts := []ast.Expr{ // 结构体的字段
  75. &ast.KeyValueExpr{
  76. Key: &ast.Ident{Name: "ParentId"},
  77. Value: &ast.BasicLit{Kind: token.INT, Value: "0"},
  78. },
  79. &ast.KeyValueExpr{
  80. Key: &ast.Ident{Name: "Path"},
  81. Value: &ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("\"%s\"", menus[i].Path)},
  82. },
  83. &ast.KeyValueExpr{
  84. Key: &ast.Ident{Name: "Name"},
  85. Value: &ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("\"%s\"", menus[i].Name)},
  86. },
  87. &ast.KeyValueExpr{
  88. Key: &ast.Ident{Name: "Hidden"},
  89. Value: &ast.Ident{Name: "false"},
  90. },
  91. &ast.KeyValueExpr{
  92. Key: &ast.Ident{Name: "Component"},
  93. Value: &ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("\"%s\"", menus[i].Component)},
  94. },
  95. &ast.KeyValueExpr{
  96. Key: &ast.Ident{Name: "Sort"},
  97. Value: &ast.BasicLit{Kind: token.INT, Value: fmt.Sprintf("%d", menus[i].Sort)},
  98. },
  99. &ast.KeyValueExpr{
  100. Key: &ast.Ident{Name: "Meta"},
  101. Value: &ast.CompositeLit{
  102. Type: &ast.SelectorExpr{
  103. X: &ast.Ident{Name: "model"},
  104. Sel: &ast.Ident{Name: "Meta"},
  105. },
  106. Elts: []ast.Expr{
  107. &ast.KeyValueExpr{
  108. Key: &ast.Ident{Name: "Title"},
  109. Value: &ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("\"%s\"", menus[i].Title)},
  110. },
  111. &ast.KeyValueExpr{
  112. Key: &ast.Ident{Name: "Icon"},
  113. Value: &ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("\"%s\"", menus[i].Icon)},
  114. },
  115. },
  116. },
  117. },
  118. }
  119. menuElts = append(menuElts, &ast.CompositeLit{
  120. Type: nil,
  121. Elts: elts,
  122. })
  123. }
  124. return &menuElts
  125. }
  126. func CreateApiStructAst(apis []system.SysApi) *[]ast.Expr {
  127. var apiElts []ast.Expr
  128. for i := range apis {
  129. elts := []ast.Expr{ // 结构体的字段
  130. &ast.KeyValueExpr{
  131. Key: &ast.Ident{Name: "Path"},
  132. Value: &ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("\"%s\"", apis[i].Path)},
  133. },
  134. &ast.KeyValueExpr{
  135. Key: &ast.Ident{Name: "Description"},
  136. Value: &ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("\"%s\"", apis[i].Description)},
  137. },
  138. &ast.KeyValueExpr{
  139. Key: &ast.Ident{Name: "ApiGroup"},
  140. Value: &ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("\"%s\"", apis[i].ApiGroup)},
  141. },
  142. &ast.KeyValueExpr{
  143. Key: &ast.Ident{Name: "Method"},
  144. Value: &ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("\"%s\"", apis[i].Method)},
  145. },
  146. }
  147. apiElts = append(apiElts, &ast.CompositeLit{
  148. Type: nil,
  149. Elts: elts,
  150. })
  151. }
  152. return &apiElts
  153. }
  154. // CheckImport 检查是否存在Import
  155. func CheckImport(file *ast.File, importPath string) bool {
  156. for _, imp := range file.Imports {
  157. // Remove quotes around the import path
  158. path := imp.Path.Value[1 : len(imp.Path.Value)-1]
  159. if path == importPath {
  160. return true
  161. }
  162. }
  163. return false
  164. }
  165. func clearPosition(astNode ast.Node) {
  166. ast.Inspect(astNode, func(n ast.Node) bool {
  167. switch node := n.(type) {
  168. case *ast.Ident:
  169. // 清除位置信息
  170. node.NamePos = token.NoPos
  171. case *ast.CallExpr:
  172. // 清除位置信息
  173. node.Lparen = token.NoPos
  174. node.Rparen = token.NoPos
  175. case *ast.BasicLit:
  176. // 清除位置信息
  177. node.ValuePos = token.NoPos
  178. case *ast.SelectorExpr:
  179. // 清除位置信息
  180. node.Sel.NamePos = token.NoPos
  181. case *ast.BinaryExpr:
  182. node.OpPos = token.NoPos
  183. case *ast.UnaryExpr:
  184. node.OpPos = token.NoPos
  185. case *ast.StarExpr:
  186. node.Star = token.NoPos
  187. }
  188. return true
  189. })
  190. }
  191. func CreateStmt(statement string) *ast.ExprStmt {
  192. expr, err := parser.ParseExpr(statement)
  193. if err != nil {
  194. log.Fatal(err)
  195. }
  196. clearPosition(expr)
  197. return &ast.ExprStmt{X: expr}
  198. }
  199. func IsBlockStmt(node ast.Node) bool {
  200. _, ok := node.(*ast.BlockStmt)
  201. return ok
  202. }
  203. func VariableExistsInBlock(block *ast.BlockStmt, varName string) bool {
  204. exists := false
  205. ast.Inspect(block, func(n ast.Node) bool {
  206. switch node := n.(type) {
  207. case *ast.AssignStmt:
  208. for _, expr := range node.Lhs {
  209. if ident, ok := expr.(*ast.Ident); ok && ident.Name == varName {
  210. exists = true
  211. return false
  212. }
  213. }
  214. }
  215. return true
  216. })
  217. return exists
  218. }