package main
import ( "encoding/json" "fmt" "go/ast" "go/parser" "go/token")
const content = `package maintype S1 struct{}func (this *S1) M1() {}func (this *S1) M2() {}func (this S1) M3() {}type S2 struct{}type S3 struct{}func (this *S3) M1() {}func (this S3) M2() {}func (this *S3) M3() {}`
func main() { fset := token.NewFileSet() f, err := parser.ParseFile(fset, "", content, parser.ParseComments) if err != nil { fmt.Println(err) return }
structInfoList := make([]*StructInfo, 0) structInfoMap := make(map[string]*StructInfo)
// 找结构体 for i := 0; i < len(f.Decls); i++ { decl, ok := f.Decls[i].(*ast.GenDecl) if !ok { continue } if decl.Tok != token.TYPE { continue } if len(decl.Specs) != 1 { continue } spec, ok2 := decl.Specs[0].(*ast.TypeSpec) if !ok2 { continue } structType, ok3 := spec.Type.(*ast.StructType) if !ok3 { fmt.Println("失败", structType) continue } structInfo := NewStructInfo(spec.Name.Name) structInfoList = append(structInfoList, structInfo) structInfoMap[spec.Name.Name] = structInfo }
// 找方法 for i := 0; i < len(f.Decls); i++ { decl, ok := f.Decls[i].(*ast.FuncDecl) if !ok { continue } if decl.Recv == nil || len(decl.Recv.List) != 1 { continue } 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 := structInfoMap[structName]; ok { structInfo.MethodNameList = append(structInfo.MethodNameList, decl.Name.Name) } }
// 输出 data, _ := json.MarshalIndent(structInfoList, "", " ") fmt.Println(string(data))}
type StructInfo struct { StructName string `json:"structName,omitempty"` MethodNameList []string `json:"methodNameList,omitempty"`}
func NewStructInfo(structName string) *StructInfo { return &StructInfo{StructName: structName, MethodNameList: make([]string, 0)}}
评论