plugin_enter.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. package ast
  2. import (
  3. "go/ast"
  4. "go/token"
  5. "io"
  6. )
  7. // PluginEnter 插件化入口
  8. // ModuleName := PackageName.GroupName.ServiceName
  9. type PluginEnter struct {
  10. Base
  11. Type Type // 类型
  12. Path string // 文件路径
  13. ImportPath string // 导包路径
  14. RelativePath string // 相对路径
  15. StructName string // 结构体名称
  16. StructCamelName string // 结构体小驼峰名称
  17. ModuleName string // 模块名称
  18. GroupName string // 分组名称
  19. PackageName string // 包名
  20. ServiceName string // 服务名称
  21. }
  22. func (a *PluginEnter) Parse(filename string, writer io.Writer) (file *ast.File, err error) {
  23. if filename == "" {
  24. if a.RelativePath == "" {
  25. filename = a.Path
  26. a.RelativePath = a.Base.RelativePath(a.Path)
  27. return a.Base.Parse(filename, writer)
  28. }
  29. a.Path = a.Base.AbsolutePath(a.RelativePath)
  30. filename = a.Path
  31. }
  32. return a.Base.Parse(filename, writer)
  33. }
  34. func (a *PluginEnter) Rollback(file *ast.File) error {
  35. //回滚结构体内内容
  36. var structType *ast.StructType
  37. ast.Inspect(file, func(n ast.Node) bool {
  38. switch x := n.(type) {
  39. case *ast.TypeSpec:
  40. if s, ok := x.Type.(*ast.StructType); ok {
  41. structType = s
  42. for i, field := range x.Type.(*ast.StructType).Fields.List {
  43. if len(field.Names) > 0 && field.Names[0].Name == a.StructName {
  44. s.Fields.List = append(s.Fields.List[:i], s.Fields.List[i+1:]...)
  45. return false
  46. }
  47. }
  48. }
  49. }
  50. return true
  51. })
  52. if len(structType.Fields.List) == 0 {
  53. _ = NewImport(a.ImportPath).Rollback(file)
  54. }
  55. if a.Type == TypePluginServiceEnter {
  56. return nil
  57. }
  58. //回滚变量内容
  59. ast.Inspect(file, func(n ast.Node) bool {
  60. genDecl, ok := n.(*ast.GenDecl)
  61. if ok && genDecl.Tok == token.VAR {
  62. for i, spec := range genDecl.Specs {
  63. valueSpec, vsok := spec.(*ast.ValueSpec)
  64. if vsok {
  65. for _, name := range valueSpec.Names {
  66. if name.Name == a.ModuleName {
  67. genDecl.Specs = append(genDecl.Specs[:i], genDecl.Specs[i+1:]...)
  68. return false
  69. }
  70. }
  71. }
  72. }
  73. }
  74. return true
  75. })
  76. return nil
  77. }
  78. func (a *PluginEnter) Injection(file *ast.File) error {
  79. _ = NewImport(a.ImportPath).Injection(file)
  80. has := false
  81. hasVar := false
  82. var firstStruct *ast.StructType
  83. var varSpec *ast.GenDecl
  84. //寻找是否存在结构且定位
  85. ast.Inspect(file, func(n ast.Node) bool {
  86. switch x := n.(type) {
  87. case *ast.TypeSpec:
  88. if s, ok := x.Type.(*ast.StructType); ok {
  89. firstStruct = s
  90. for _, field := range x.Type.(*ast.StructType).Fields.List {
  91. if len(field.Names) > 0 && field.Names[0].Name == a.StructName {
  92. has = true
  93. return false
  94. }
  95. }
  96. }
  97. }
  98. return true
  99. })
  100. if !has {
  101. field := &ast.Field{
  102. Names: []*ast.Ident{{Name: a.StructName}},
  103. Type: &ast.Ident{Name: a.StructCamelName},
  104. }
  105. firstStruct.Fields.List = append(firstStruct.Fields.List, field)
  106. }
  107. if a.Type == TypePluginServiceEnter {
  108. return nil
  109. }
  110. //寻找是否存在变量且定位
  111. ast.Inspect(file, func(n ast.Node) bool {
  112. genDecl, ok := n.(*ast.GenDecl)
  113. if ok && genDecl.Tok == token.VAR {
  114. for _, spec := range genDecl.Specs {
  115. valueSpec, vsok := spec.(*ast.ValueSpec)
  116. if vsok {
  117. varSpec = genDecl
  118. for _, name := range valueSpec.Names {
  119. if name.Name == a.ModuleName {
  120. hasVar = true
  121. return false
  122. }
  123. }
  124. }
  125. }
  126. }
  127. return true
  128. })
  129. if !hasVar {
  130. spec := &ast.ValueSpec{
  131. Names: []*ast.Ident{{Name: a.ModuleName}},
  132. Values: []ast.Expr{
  133. &ast.SelectorExpr{
  134. X: &ast.SelectorExpr{
  135. X: &ast.Ident{Name: a.PackageName},
  136. Sel: &ast.Ident{Name: a.GroupName},
  137. },
  138. Sel: &ast.Ident{Name: a.ServiceName},
  139. },
  140. },
  141. }
  142. varSpec.Specs = append(varSpec.Specs, spec)
  143. }
  144. return nil
  145. }
  146. func (a *PluginEnter) Format(filename string, writer io.Writer, file *ast.File) error {
  147. if filename == "" {
  148. filename = a.Path
  149. }
  150. return a.Base.Format(filename, writer, file)
  151. }