github.com/gotranspile/cxgo@v0.3.7/go_print.go (about) 1 package cxgo 2 3 import ( 4 "go/ast" 5 "go/format" 6 token2 "go/token" 7 "io" 8 "sort" 9 "strconv" 10 "strings" 11 12 "github.com/gotranspile/cxgo/libs" 13 ) 14 15 func PrintGo(w io.Writer, pkg string, decls []GoDecl) error { 16 return format.Node(w, token2.NewFileSet(), &ast.File{Decls: decls, Name: ident(pkg)}) 17 } 18 19 type usageVisitor struct { 20 used map[string]struct{} 21 } 22 23 func (v *usageVisitor) Visit(n ast.Node) ast.Visitor { 24 switch n := n.(type) { 25 case *ast.Ident: 26 sub := strings.SplitN(n.Name, ".", 2) 27 if len(sub) == 2 { 28 v.used[sub[0]] = struct{}{} 29 } 30 } 31 return v 32 } 33 34 func goUsedImports(used map[string]struct{}, decls []GoDecl) { 35 for _, d := range decls { 36 ast.Walk(&usageVisitor{used: used}, d) 37 } 38 } 39 40 // ImportsFor generates import specs for well-known imports required for given declarations. 41 func ImportsFor(e *libs.Env, decls []GoDecl) []GoDecl { 42 used := make(map[string]struct{}) 43 goUsedImports(used, decls) 44 var list []string 45 for k := range used { 46 list = append(list, k) 47 } 48 sort.Strings(list) 49 var specs []ast.Spec 50 for _, name := range list { 51 path := e.ResolveImport(name) 52 specs = append(specs, &ast.ImportSpec{Path: &ast.BasicLit{ 53 Kind: token2.STRING, 54 Value: strconv.Quote(path), 55 }}) 56 } 57 if len(specs) == 0 { 58 return nil 59 } 60 return []GoDecl{ 61 &ast.GenDecl{ 62 Tok: token2.IMPORT, 63 Specs: specs, 64 }, 65 } 66 }