github.com/goplus/gogen@v1.16.0/gow.go (about) 1 /* 2 Copyright 2021 The GoPlus Authors (goplus.org) 3 Licensed under the Apache License, Version 2.0 (the "License"); 4 you may not use this file except in compliance with the License. 5 You may obtain a copy of the License at 6 http://www.apache.org/licenses/LICENSE-2.0 7 Unless required by applicable law or agreed to in writing, software 8 distributed under the License is distributed on an "AS IS" BASIS, 9 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 See the License for the specific language governing permissions and 11 limitations under the License. 12 */ 13 14 package gogen 15 16 import ( 17 "go/ast" 18 "go/token" 19 "go/types" 20 "io" 21 "log" 22 "os" 23 "syscall" 24 25 "github.com/goplus/gogen/internal/go/format" 26 "github.com/goplus/gogen/internal/go/printer" 27 ) 28 29 // ---------------------------------------------------------------------------- 30 31 // TypeAST returns the AST of specified typ. 32 func TypeAST(pkg *Package, typ types.Type) ast.Expr { 33 return toType(pkg, typ) 34 } 35 36 // ASTFile returns AST of a file by its fname. 37 // If fname is not provided, it returns AST of the default (NOT current) file. 38 func (p *Package) ASTFile(fname ...string) *ast.File { 39 f, ok := p.File(fname...) 40 if !ok { 41 return nil 42 } 43 if debugWriteFile { 44 log.Println("==> ASTFile", f.Name()) 45 } 46 decls := f.getDecls(p) 47 file := &ast.File{Name: ident(p.Types.Name()), Decls: decls, Imports: getImports(decls)} 48 return file 49 } 50 51 func getImports(decls []ast.Decl) []*ast.ImportSpec { 52 if len(decls) > 0 { 53 if decl, ok := decls[0].(*ast.GenDecl); ok && decl.Tok == token.IMPORT { 54 n := len(decl.Specs) 55 ret := make([]*ast.ImportSpec, n) 56 for i, spec := range decl.Specs { 57 ret[i] = spec.(*ast.ImportSpec) 58 } 59 return ret 60 } 61 } 62 return nil 63 } 64 65 // CommentedASTFile returns commented AST of a file by its fname. 66 // If fname is not provided, it returns AST of the default (NOT current) file. 67 func (p *Package) CommentedASTFile(fname ...string) *printer.CommentedNodes { 68 f := p.ASTFile(fname...) 69 if f == nil { 70 return nil 71 } 72 return &printer.CommentedNodes{ 73 Node: f, 74 CommentedStmts: p.commentedStmts, 75 } 76 } 77 78 // WriteTo writes a file named fname to dst. 79 // If fname is not provided, it writes the default (NOT current) file. 80 func (p *Package) WriteTo(dst io.Writer, fname ...string) (err error) { 81 file := p.CommentedASTFile(fname...) 82 if file == nil { 83 return syscall.ENOENT 84 } 85 fset := token.NewFileSet() 86 return format.Node(dst, fset, file) 87 } 88 89 // GeneratedHeader is the default string that the source file generated by gogen start with. 90 // Change it if you want to make it different. 91 var ( 92 GeneratedHeader = "// Code generated by gogen; DO NOT EDIT.\n\n" 93 ) 94 95 // WriteFile writes a file named fname. 96 // If fname is not provided, it writes the default (NOT current) file. 97 func (p *Package) WriteFile(file string, fname ...string) (err error) { 98 ast := p.CommentedASTFile(fname...) 99 if ast == nil { 100 return syscall.ENOENT 101 } 102 if debugWriteFile { 103 log.Println("WriteFile", file) 104 } 105 f, err := os.Create(file) 106 if err != nil { 107 return 108 } 109 err = syscall.EFAULT 110 defer func() { 111 f.Close() 112 if err != nil { 113 os.Remove(file) 114 } 115 }() 116 if GeneratedHeader != "" { 117 f.WriteString(GeneratedHeader) 118 } 119 fset := token.NewFileSet() 120 return format.Node(f, fset, ast) 121 } 122 123 // ---------------------------------------------------------------------------- 124 125 // ASTFile returns AST of a file by its fname. 126 // If fname is not provided, it returns AST of the default (NOT current) file. 127 // 128 // Deprecated: Use pkg.ASTFile instead. 129 func ASTFile(pkg *Package, fname ...string) *ast.File { 130 return pkg.ASTFile(fname...) 131 } 132 133 // CommentedASTFile returns commented AST of a file by its fname. 134 // If fname is not provided, it returns AST of the default (NOT current) file. 135 // 136 // Deprecated: Use pkg.CommentedASTFile instead. 137 func CommentedASTFile(pkg *Package, fname ...string) *printer.CommentedNodes { 138 return pkg.CommentedASTFile(fname...) 139 } 140 141 // WriteTo writes a file named fname to dst. 142 // If fname is not provided, it writes the default (NOT current) file. 143 // 144 // Deprecated: Use pkg.WriteTo instead. 145 func WriteTo(dst io.Writer, pkg *Package, fname ...string) (err error) { 146 return pkg.WriteTo(dst, fname...) 147 } 148 149 // WriteFile writes a file named fname. 150 // If fname is not provided, it writes the default (NOT current) file. 151 // 152 // Deprecated: Use pkg.WriteTo instead. 153 func WriteFile(file string, pkg *Package, fname ...string) (err error) { 154 return pkg.WriteFile(file, fname...) 155 } 156 157 // ----------------------------------------------------------------------------