ast_base.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. package ams_ast
  2. import (
  3. "fmt"
  4. "go/ast"
  5. "go/token"
  6. "path/filepath"
  7. "strings"
  8. )
  9. type BaseAst struct {
  10. }
  11. // 添加导入声明
  12. func (BaseAst) AddImport(f *ast.File, importPath string) {
  13. // 规范化导入路径,确保跨平台兼容性
  14. normalizedPath := filepath.ToSlash(strings.TrimSpace(importPath))
  15. for _, imp := range f.Imports {
  16. if strings.Trim(imp.Path.Value, `"`) == normalizedPath {
  17. return // 已经存在该导入
  18. }
  19. }
  20. // 创建新的导入声明
  21. newImport := &ast.ImportSpec{
  22. Path: &ast.BasicLit{
  23. Kind: token.STRING,
  24. Value: fmt.Sprintf(`"%s"`, normalizedPath),
  25. },
  26. }
  27. // 添加到导入声明列表
  28. f.Imports = append(f.Imports, newImport)
  29. // 找到第一个 GenDecl(导入声明块)
  30. for _, decl := range f.Decls {
  31. if genDecl, ok := decl.(*ast.GenDecl); ok && genDecl.Tok == token.IMPORT {
  32. // 添加到现有的导入声明块
  33. genDecl.Specs = append(genDecl.Specs, newImport)
  34. return
  35. }
  36. }
  37. // 如果没有找到导入声明块,创建一个新的
  38. importDecl := &ast.GenDecl{
  39. Tok: token.IMPORT,
  40. Specs: []ast.Spec{
  41. newImport,
  42. },
  43. }
  44. // 将新的导入声明添加到文件开头
  45. newDecls := []ast.Decl{importDecl}
  46. f.Decls = append(newDecls, f.Decls...)
  47. }
  48. // 移除指定的导入
  49. func (BaseAst) RemoveImport(f *ast.File, importPath string) {
  50. // 1. 从 f.Imports 中移除
  51. newImports := make([]*ast.ImportSpec, 0, len(f.Imports))
  52. for _, imp := range f.Imports {
  53. if strings.Trim(imp.Path.Value, `"`) != importPath {
  54. newImports = append(newImports, imp)
  55. }
  56. }
  57. f.Imports = newImports
  58. // 2. 从导入声明中移除
  59. for _, decl := range f.Decls {
  60. if genDecl, ok := decl.(*ast.GenDecl); ok && genDecl.Tok == token.IMPORT {
  61. newSpecs := make([]ast.Spec, 0, len(genDecl.Specs))
  62. for _, spec := range genDecl.Specs {
  63. if impSpec, ok := spec.(*ast.ImportSpec); ok {
  64. if strings.Trim(impSpec.Path.Value, `"`) != importPath {
  65. newSpecs = append(newSpecs, spec)
  66. }
  67. } else {
  68. newSpecs = append(newSpecs, spec)
  69. }
  70. }
  71. genDecl.Specs = newSpecs
  72. // 如果导入声明为空,可以移除整个声明
  73. if len(genDecl.Specs) == 0 {
  74. newDecls := make([]ast.Decl, 0, len(f.Decls))
  75. for _, d := range f.Decls {
  76. if d != decl {
  77. newDecls = append(newDecls, d)
  78. }
  79. }
  80. f.Decls = newDecls
  81. }
  82. }
  83. }
  84. }
  85. // 检查元素列表中是否已注入指定结果体 demo.RouterGroup{}
  86. func (BaseAst) IsContainsModule(elts []ast.Expr, moduleName, structName string) bool {
  87. for _, elt := range elts {
  88. if compLit, ok := elt.(*ast.CompositeLit); ok {
  89. if selExpr, ok := compLit.Type.(*ast.SelectorExpr); ok {
  90. if xIdent, ok := selExpr.X.(*ast.Ident); ok && xIdent.Name == moduleName {
  91. if selExpr.Sel.Name == structName {
  92. return true
  93. }
  94. }
  95. }
  96. }
  97. }
  98. return false
  99. }
  100. // 检查是否为指定模块
  101. func (BaseAst) IsTargetModule(expr ast.Expr, moduleName, structName string) bool {
  102. if compLit, ok := expr.(*ast.CompositeLit); ok {
  103. if selExpr, ok := compLit.Type.(*ast.SelectorExpr); ok {
  104. if xIdent, ok := selExpr.X.(*ast.Ident); ok && xIdent.Name == moduleName {
  105. if selExpr.Sel.Name == structName {
  106. return true
  107. }
  108. }
  109. }
  110. }
  111. return false
  112. }
  113. // 检查文件中指定结构体是否存在某属性
  114. func (BaseAst) CheckFileStructHasFiled(file *ast.File, structName, filedName string) bool {
  115. // 检查是否已存在 UserServiceGroup
  116. hasService := false
  117. ast.Inspect(file, func(n ast.Node) bool {
  118. if compLit, ok := n.(*ast.CompositeLit); ok {
  119. if selExpr, ok := compLit.Type.(*ast.SelectorExpr); ok {
  120. if selExpr.Sel.Name == structName {
  121. for _, elt := range compLit.Elts {
  122. if kv, ok := elt.(*ast.KeyValueExpr); ok {
  123. if ident, ok := kv.Key.(*ast.Ident); ok && ident.Name == filedName {
  124. hasService = true
  125. return false
  126. }
  127. }
  128. }
  129. }
  130. }
  131. }
  132. return true
  133. })
  134. return hasService
  135. }
  136. // 检查文件中是否存在 struct 声明(类声明)
  137. func (BaseAst) FindFileHasStruct(file *ast.File, className string) (*ast.TypeSpec, bool) {
  138. var classTypeSpec *ast.TypeSpec
  139. ast.Inspect(file, func(n ast.Node) bool {
  140. // 查找类型声明
  141. if typeSpec, ok := n.(*ast.TypeSpec); ok {
  142. //core.Log.Infof("查找文件中是否存在类型申明 typeSpec.Name.Name:%s", typeSpec.Name.Name)
  143. if typeSpec.Name.Name == className {
  144. classTypeSpec = typeSpec
  145. // 检查结构体类型
  146. return false
  147. }
  148. }
  149. return true
  150. })
  151. if classTypeSpec == nil {
  152. return nil, false
  153. }
  154. return classTypeSpec, true
  155. }