package ast import ( "go/ast" "go/format" "go/parser" "go/token" "os" "errors" ) type ASTer struct { pkg string fname string fset *token.FileSet node *ast.File } func NewASTer() (*ASTer, error) { a := &ASTer{} pkg, err := получитьИмяGoПакетаВЭтойДире() if err != nil { return nil, err } a.pkg = pkg err = a.найтиТестовыйФайл() if err != nil { return nil, err } return a, nil } func (a *ASTer) ДобавитьТестовуюФункцию(func_name string) error { return a.добавитьвФайлФункцию(func_name) } func (a *ASTer) найтиТестовыйФайл() error { a.сгенеритьИмяФайла() _, err := os.Stat(a.fname) return err } func (a *ASTer) сгенеритьИмяФайла() { a.fname = a.pkg + "_test.go" } func (a *ASTer) добавитьвФайлФункцию(func_name string) error { err := a.спарситьФайлиДобавитьФункцию(func_name) if err != nil { return err } return a.перезаписатьФайл() } func (a *ASTer) спарситьФайлиДобавитьФункцию(func_name string) error { err := a.спарситьФайл() if err != nil { return err } fun := a.пустаяФункция(func_name) a.node.Decls = append(a.node.Decls, fun) return nil } func (a *ASTer) спарситьФайл() error { fset := token.NewFileSet() node, err := parser.ParseFile(fset, a.fname, nil, parser.ParseComments) a.fset = fset a.node = node return err } func (a *ASTer) пустаяФункция(func_name string) *ast.FuncDecl { return &ast.FuncDecl{ Name: ast.NewIdent(func_name), Type: &ast.FuncType{ Params: &ast.FieldList{}, Results: &ast.FieldList{}, }, Body: &ast.BlockStmt{}, } } func (a *ASTer) перезаписатьФайл() error { err := переименоватьФайлСоВременем(a.fname) if err != nil { return errors.Join(err, errors.New("cant backup orig file")) } f, err := os.Create(a.fname) if err != nil { return errors.Join(err, errors.New("cant rewrite orig file")) } defer f.Close() return format.Node(f, a.fset, a.node) }