ast.go 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  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. // 添加菜单参数
  120. if len(menus[i].Parameters) > 0 {
  121. var paramElts []ast.Expr
  122. for _, param := range menus[i].Parameters {
  123. paramElts = append(paramElts, &ast.CompositeLit{
  124. Type: &ast.SelectorExpr{
  125. X: &ast.Ident{Name: "model"},
  126. Sel: &ast.Ident{Name: "SysBaseMenuParameter"},
  127. },
  128. Elts: []ast.Expr{
  129. &ast.KeyValueExpr{
  130. Key: &ast.Ident{Name: "Type"},
  131. Value: &ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("\"%s\"", param.Type)},
  132. },
  133. &ast.KeyValueExpr{
  134. Key: &ast.Ident{Name: "Key"},
  135. Value: &ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("\"%s\"", param.Key)},
  136. },
  137. &ast.KeyValueExpr{
  138. Key: &ast.Ident{Name: "Value"},
  139. Value: &ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("\"%s\"", param.Value)},
  140. },
  141. },
  142. })
  143. }
  144. elts = append(elts, &ast.KeyValueExpr{
  145. Key: &ast.Ident{Name: "Parameters"},
  146. Value: &ast.CompositeLit{
  147. Type: &ast.ArrayType{
  148. Elt: &ast.SelectorExpr{
  149. X: &ast.Ident{Name: "model"},
  150. Sel: &ast.Ident{Name: "SysBaseMenuParameter"},
  151. },
  152. },
  153. Elts: paramElts,
  154. },
  155. })
  156. }
  157. // 添加菜单按钮
  158. if len(menus[i].MenuBtn) > 0 {
  159. var btnElts []ast.Expr
  160. for _, btn := range menus[i].MenuBtn {
  161. btnElts = append(btnElts, &ast.CompositeLit{
  162. Type: &ast.SelectorExpr{
  163. X: &ast.Ident{Name: "model"},
  164. Sel: &ast.Ident{Name: "SysBaseMenuBtn"},
  165. },
  166. Elts: []ast.Expr{
  167. &ast.KeyValueExpr{
  168. Key: &ast.Ident{Name: "Name"},
  169. Value: &ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("\"%s\"", btn.Name)},
  170. },
  171. &ast.KeyValueExpr{
  172. Key: &ast.Ident{Name: "Desc"},
  173. Value: &ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("\"%s\"", btn.Desc)},
  174. },
  175. },
  176. })
  177. }
  178. elts = append(elts, &ast.KeyValueExpr{
  179. Key: &ast.Ident{Name: "MenuBtn"},
  180. Value: &ast.CompositeLit{
  181. Type: &ast.ArrayType{
  182. Elt: &ast.SelectorExpr{
  183. X: &ast.Ident{Name: "model"},
  184. Sel: &ast.Ident{Name: "SysBaseMenuBtn"},
  185. },
  186. },
  187. Elts: btnElts,
  188. },
  189. })
  190. }
  191. menuElts = append(menuElts, &ast.CompositeLit{
  192. Type: nil,
  193. Elts: elts,
  194. })
  195. }
  196. return &menuElts
  197. }
  198. func CreateApiStructAst(apis []system.SysApi) *[]ast.Expr {
  199. var apiElts []ast.Expr
  200. for i := range apis {
  201. elts := []ast.Expr{ // 结构体的字段
  202. &ast.KeyValueExpr{
  203. Key: &ast.Ident{Name: "Path"},
  204. Value: &ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("\"%s\"", apis[i].Path)},
  205. },
  206. &ast.KeyValueExpr{
  207. Key: &ast.Ident{Name: "Description"},
  208. Value: &ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("\"%s\"", apis[i].Description)},
  209. },
  210. &ast.KeyValueExpr{
  211. Key: &ast.Ident{Name: "ApiGroup"},
  212. Value: &ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("\"%s\"", apis[i].ApiGroup)},
  213. },
  214. &ast.KeyValueExpr{
  215. Key: &ast.Ident{Name: "Method"},
  216. Value: &ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("\"%s\"", apis[i].Method)},
  217. },
  218. }
  219. apiElts = append(apiElts, &ast.CompositeLit{
  220. Type: nil,
  221. Elts: elts,
  222. })
  223. }
  224. return &apiElts
  225. }
  226. // CheckImport 检查是否存在Import
  227. func CheckImport(file *ast.File, importPath string) bool {
  228. for _, imp := range file.Imports {
  229. // Remove quotes around the import path
  230. path := imp.Path.Value[1 : len(imp.Path.Value)-1]
  231. if path == importPath {
  232. return true
  233. }
  234. }
  235. return false
  236. }
  237. func clearPosition(astNode ast.Node) {
  238. ast.Inspect(astNode, func(n ast.Node) bool {
  239. switch node := n.(type) {
  240. case *ast.Ident:
  241. // 清除位置信息
  242. node.NamePos = token.NoPos
  243. case *ast.CallExpr:
  244. // 清除位置信息
  245. node.Lparen = token.NoPos
  246. node.Rparen = token.NoPos
  247. case *ast.BasicLit:
  248. // 清除位置信息
  249. node.ValuePos = token.NoPos
  250. case *ast.SelectorExpr:
  251. // 清除位置信息
  252. node.Sel.NamePos = token.NoPos
  253. case *ast.BinaryExpr:
  254. node.OpPos = token.NoPos
  255. case *ast.UnaryExpr:
  256. node.OpPos = token.NoPos
  257. case *ast.StarExpr:
  258. node.Star = token.NoPos
  259. }
  260. return true
  261. })
  262. }
  263. func CreateStmt(statement string) *ast.ExprStmt {
  264. expr, err := parser.ParseExpr(statement)
  265. if err != nil {
  266. log.Fatal(err)
  267. }
  268. clearPosition(expr)
  269. return &ast.ExprStmt{X: expr}
  270. }
  271. func IsBlockStmt(node ast.Node) bool {
  272. _, ok := node.(*ast.BlockStmt)
  273. return ok
  274. }
  275. func VariableExistsInBlock(block *ast.BlockStmt, varName string) bool {
  276. exists := false
  277. ast.Inspect(block, func(n ast.Node) bool {
  278. switch node := n.(type) {
  279. case *ast.AssignStmt:
  280. for _, expr := range node.Lhs {
  281. if ident, ok := expr.(*ast.Ident); ok && ident.Name == varName {
  282. exists = true
  283. return false
  284. }
  285. }
  286. }
  287. return true
  288. })
  289. return exists
  290. }