1 Star 0 Fork 0

ichub / goconfig

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
di_factroy.go 8.16 KB
一键复制 编辑 原始数据 按行查看 历史
leijmdas 提交于 2024-05-05 12:11 . add
package difactroy
import (
"gitee.com/ichub/goconfig/common/base/basedto"
"gitee.com/ichub/goconfig/common/base/baseutils/fileutils"
"gitee.com/ichub/goconfig/common/base/baseutils/jsonutils"
"gitee.com/ichub/goconfig/common/base/baseutils/stringutils"
"gitee.com/ichub/goconfig/common/ichublog"
"gitee.com/ichub/goconfig/godi/codefactroy"
"gitee.com/ichub/goconfig/godi/didto"
"github.com/duke-git/lancet/fileutil"
"github.com/sirupsen/logrus"
"go/ast"
"go/parser"
"go/token"
"os"
"path/filepath"
"strings"
)
const dataOutputDiStruct = "/data/output/di/struct"
const dataOutputDiStructFile = "/data/output/di/file"
type DiFactroy struct {
basedto.BaseEntitySingle
BasePkg string
Rootdir string
FileInfoDtos []*FileinfoDto
StructInfos [][]*StructInfo
StructInfoMap map[string]*StructInfo
}
func NewDiFactroy() *DiFactroy {
return (&DiFactroy{
Rootdir: fileutils.FindRootDir(),
FileInfoDtos: make([]*FileinfoDto, 0),
StructInfoMap: make(map[string]*StructInfo),
}).init()
}
func (this *DiFactroy) init() *DiFactroy {
ichublog.InitLogrus()
this.BasePkg = this.FindBasePkg()
return this
}
func (this *DiFactroy) MakeDi(dto *didto.DiDto) error {
return codefactroy.MakeDi(dto)
}
func (this *DiFactroy) MakeBatch(structInfo *StructInfo) bool {
if !structInfo.IsBaseEntiyStruct {
return false
}
var dto = structInfo.DiDto
dto.OutPath = filepath.Dir(structInfo.PathFile)
this.MakeDi(dto)
return true
}
func (this *DiFactroy) FindBasePkg() string {
var content, _ = fileutil.ReadFileToString(fileutils.FindRootDirGoMod() + "/go.mod")
var lines = strings.Split(content, "\n")
for _, line := range lines {
if strings.Contains(line, "module") {
var lineArr = strings.Split(line, "module")
this.BasePkg = strings.Trim(lineArr[1], " ")
this.BasePkg = strings.Trim(this.BasePkg, "\r")
return this.BasePkg
}
}
return ""
}
func (this *DiFactroy) FindFile(file string) *FileinfoDto {
fset := token.NewFileSet()
// 这里取绝对路径,方便打印出来的语法树可以转跳到编辑器
path, _ := filepath.Abs(file)
_, err := parser.ParseFile(fset, path, nil, parser.AllErrors)
if err != nil {
logrus.Println(err)
return nil
}
// 打印语法树 ast.Print(fset, f.Scope.Objects)
var fi = &FileinfoDto{
//AstFile: f,
PathFile: path,
}
return fi
}
func (this *DiFactroy) FindGoFiles() error {
// 指定需要遍历的目录
dirPath := this.Rootdir
// 使用filepath.Walk遍历目录
err := filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error {
if err != nil {
logrus.Error(err)
return err
}
// 如果是文件,可以进行额外操作,比如读取文件内容
if !info.IsDir() {
if !strings.HasSuffix(path, "_test.go") &&
strings.HasSuffix(path, ".go") {
var somepath = strings.Split(path, this.Rootdir)
var some = strings.Replace(path, this.Rootdir, "", -1)
var file = NewFileInfoDto()
file.PathFile = this.Rootdir + some
if len(somepath) > 1 {
this.FileInfoDtos = append(this.FileInfoDtos, file)
}
}
}
// 返回nil继续遍历
return nil
})
if err != nil {
logrus.Error("Error walking the path:", err)
}
return err
}
func (this *DiFactroy) ParseDir(pathf string) {
path, _ := filepath.Abs(pathf)
fset := token.NewFileSet()
pkgs, err := parser.ParseDir(fset, path, nil, parser.ParseComments)
if err != nil {
logrus.Error(err)
return
}
if pkgs == nil {
pkgs = map[string]*ast.Package{}
}
logrus.Error(path)
}
func (this *DiFactroy) MakeDiAll() {
this.ParseAll()
for _, v := range this.FileInfoDtos {
for _, vv := range v.StructInfos {
if vv.IsBaseEntiyStruct {
this.MakeBatch(vv)
}
}
}
}
func (this *DiFactroy) FindSome(struname string) *FileinfoDto {
for _, v := range this.FileInfoDtos {
for _, vv := range v.StructInfos {
if vv.StructName == struname {
return v
}
}
}
return nil
}
func (this *DiFactroy) ParseAll() {
this.FindGoFiles()
for _, v := range this.FileInfoDtos {
var fileinfo = this.Parse(v.PathFile)
this.FileInfoDtos = append(this.FileInfoDtos, fileinfo)
for _, vv := range fileinfo.StructInfos {
v.StructInfoMap[vv.PkgName+"::"+vv.StructName] = vv
}
}
this.Pasre2JsonFile()
}
func (this *DiFactroy) Pasre2JsonFile() {
var path = this.Rootdir + dataOutputDiStruct
os.Remove(path)
os.MkdirAll(path, os.ModePerm)
for _, v := range this.StructInfoMap {
if !v.IsBaseEntiyStruct {
continue
}
var jsonStr = jsonutils.ToJsonPretty(v)
var fileName = v.StructName + ".json"
var filePath = path + "/" + fileName
fileutil.WriteBytesToFile(filePath, []byte(jsonStr))
logrus.Info(filePath)
}
}
func (this *DiFactroy) ParseOneStruct(decl *ast.GenDecl, nodes *ast.File, path string) *StructInfo {
if decl.Tok != token.TYPE {
return nil
}
if len(decl.Specs) != 1 {
return nil
}
spec, ok2 := decl.Specs[0].(*ast.TypeSpec)
if !ok2 {
return nil
}
structType, ok3 := spec.Type.(*ast.StructType)
if !ok3 {
logrus.Error("失败", structType)
return nil
}
var fields = []string{}
for _, v := range structType.Fields.List {
if len(v.Names) > 0 {
fields = append(fields, v.Names[0].Name)
} else {
var expr, ok4 = v.Type.(*ast.SelectorExpr)
if ok4 {
fields = append(fields, expr.Sel.Name)
} else {
logrus.Info(1)
}
}
}
structInfo := NewStructInfo()
structInfo.Fields = fields
structInfo.PkgName = nodes.Name.Name
structInfo.PathFile = path
structInfo.StructName = spec.Name.Name
structInfo.ParsePkgName(this.Rootdir, this.BasePkg)
this.StructInfoMap[spec.Name.Name] = structInfo
structInfo.CheckBaseEntity()
return structInfo
}
func (this *DiFactroy) ParseFunc(decl *ast.FuncDecl) {
structName := ""
switch decl.Recv.List[0].Type.(type) {
case *ast.StarExpr: //指针方法
structName = decl.Recv.List[0].Type.(*ast.StarExpr).X.(*ast.Ident).Name
case *ast.Ident: //普通方法 //
structName = decl.Recv.List[0].Type.(*ast.Ident).Name
}
if structInfo, ok := this.StructInfoMap[structName]; ok {
structInfo.MethodNames = append(structInfo.MethodNames, decl.Name.Name)
}
}
func (this *DiFactroy) ExistNewFunc(nodes *ast.File, functionName string) bool {
var found = false
for _, obj := range nodes.Scope.Objects {
decl, ok := obj.Decl.(*ast.FuncDecl)
if ok {
if decl.Name.Name == functionName {
found = true
if decl.Type.Params != nil && len(decl.Type.Params.List) > 0 {
found = false
}
}
}
}
return found
}
func (this *DiFactroy) findNewFunc(node *ast.File, functionName string) bool {
found := false
ast.Inspect(node, func(n ast.Node) bool {
if fd, ok := n.(*ast.FuncDecl); ok {
if fd.Name.Name == functionName {
found = true
if fd.Type.Params != nil {
found = false
}
return false // 停止遍历
}
}
return true // 继续遍历
})
return found
}
func (this *DiFactroy) Parse(file string) *FileinfoDto {
path, _ := filepath.Abs(file)
fset := token.NewFileSet()
nodes, err := parser.ParseFile(fset, path, nil, parser.ParseComments)
if err != nil {
logrus.Error(err)
return nil
}
logrus.Info(nodes.Name)
structInfoList := make([]*StructInfo, 0)
for i := 0; i < len(nodes.Decls); i++ {
decl, ok := nodes.Decls[i].(*ast.GenDecl)
if !ok {
continue
}
var stru = this.ParseOneStruct(decl, nodes, path)
if stru != nil {
stru.NewStructName = stru.NewStruMethod()
stru.ExistNewStruct = this.ExistNewFunc(nodes, stru.NewStructName)
if !stru.ExistNewStruct {
stru.NewStructName = stringutils.Lcfirst(stru.NewStruMethod())
stru.ExistNewStruct = this.ExistNewFunc(nodes, stru.NewStructName)
}
}
if stru != nil {
structInfoList = append(structInfoList, stru)
}
} // 找方法
for i := 0; i < len(nodes.Decls); i++ {
decl, ok := nodes.Decls[i].(*ast.FuncDecl)
if !ok {
continue
}
if decl.Recv == nil || len(decl.Recv.List) != 1 {
continue
}
this.ParseFunc(decl)
}
var fileinfo = NewFileInfoDto()
for k, obj := range nodes.Scope.Objects {
logrus.Info(k)
decl, oks := obj.Decl.(*ast.FuncDecl)
if oks {
logrus.Info(decl.Name.Name)
fileinfo.Funcs = append(fileinfo.Funcs, decl.Name.Name)
}
}
fileinfo.StructInfos = structInfoList
fileinfo.PathFile = path
// 输出
logrus.Info(jsonutils.ToJsonPretty(fileinfo))
return fileinfo
}
1
https://gitee.com/ichub/goconfig.git
git@gitee.com:ichub/goconfig.git
ichub
goconfig
goconfig
v1.0.403

搜索帮助