github.com/goplus/gossa@v0.3.25/cmd/qexp/export.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "go/format" 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 "sort" 10 "strings" 11 ) 12 13 func writeFile(dir string, file string, data []byte) error { 14 err := os.MkdirAll(dir, 0777) 15 if err != nil { 16 return fmt.Errorf("make dir %v error: %v", dir, err) 17 } 18 filename := filepath.Join(dir, file) 19 err = ioutil.WriteFile(filename, data, 0777) 20 if err != nil { 21 return fmt.Errorf("write file %v error: %v", filename, err) 22 } 23 return nil 24 } 25 26 func joinList(list []string) string { 27 if len(list) == 0 { 28 return "" 29 } 30 sort.Strings(list) 31 return "\n\t" + strings.Join(list, ",\n\t") + ",\n" 32 } 33 34 func exportPkg(pkg *Package, sname string, id string, tagList []string) ([]byte, error) { 35 imports := []string{fmt.Sprintf("%v %q\n", sname, pkg.Path)} 36 imports = append(imports, `"reflect"`) 37 if len(pkg.UntypedConsts) > 0 || len(pkg.TypedConsts) > 0 { 38 imports = append(imports, `"go/constant"`) 39 var hasToken bool 40 for _, c := range pkg.UntypedConsts { 41 if strings.Index(c, "token.") >= 0 { 42 hasToken = true 43 break 44 } 45 } 46 if hasToken { 47 imports = append(imports, `"go/token"`) 48 } 49 } 50 51 r := strings.NewReplacer("$PKGNAME", pkg.Name, 52 "$IMPORTS", strings.Join(imports, "\n"), 53 "$PKGPATH", pkg.Path, 54 "$DEPS", joinList(pkg.Deps), 55 "$NAMEDTYPES", joinList(pkg.NamedTypes), 56 "$INTERFACES", joinList(pkg.Interfaces), 57 "$ALIASTYPES", joinList(pkg.AliasTypes), 58 "$VARS", joinList(pkg.Vars), 59 "$FUNCS", joinList(pkg.Funcs), 60 "$METHODS", joinList(pkg.Methods), 61 "$TYPEDCONSTS", joinList(pkg.TypedConsts), 62 "$UNTYPEDCONSTS", joinList(pkg.UntypedConsts), 63 "$TAGS", strings.Join(tagList, "\n"), 64 "$ID", id) 65 src := r.Replace(template_pkg) 66 data, err := format.Source([]byte(src)) 67 if err != nil { 68 return nil, fmt.Errorf("format pkg %v error: %v", src, err) 69 } 70 return data, nil 71 } 72 73 func exportSource(pkgPath string, id string, tagList []string, extList []string, typList []string) ([]byte, error) { 74 plist := strings.Split(pkgPath, "/") 75 pkgName := plist[len(plist)-1] 76 var em string 77 if len(extList) > 0 { 78 sort.Strings(extList) 79 em = "\n\t" + strings.Join(extList, ",\n\t") + ",\n" 80 } 81 var tl string 82 if len(typList) > 0 { 83 sort.Strings(typList) 84 tl = "\n\t" + strings.Join(typList, ",\n\t") + ",\n" 85 } 86 r := strings.NewReplacer("$PKGNAME", pkgName, 87 "$PKGPATH", pkgPath, 88 "$EXTMAP", em, 89 "$TYPLIST", tl, 90 "$TAGS", strings.Join(tagList, "\n"), 91 "$ID", id) 92 var template string 93 if len(typList) == 0 && len(extList) == 0 { 94 template = template_empty 95 } else { 96 template = template_tags 97 } 98 src := r.Replace(template) 99 data, err := format.Source([]byte(src)) 100 if err != nil { 101 return nil, fmt.Errorf("format pkg %v error: %v", pkgPath, err) 102 } 103 return data, nil 104 } 105 106 var template_export = `// export by github.com/goplus/gossa/cmd/qexp 107 package $PKGNAME 108 109 import ( 110 "$PKGPATH" 111 112 "github.com/goplus/gossa" 113 ) 114 115 func init() { 116 gossa.RegisterPackage("$PKGPATH",extMap,typList) 117 } 118 119 var extMap = map[string]interface{}{$EXTMAP} 120 121 var typList = []interface{}{$TYPLIST} 122 ` 123 124 var template_tags = `// export by github.com/goplus/gossa/cmd/qexp 125 126 $TAGS 127 128 package $PKGNAME 129 130 import ( 131 "$PKGPATH" 132 133 "github.com/goplus/gossa" 134 ) 135 136 func init() { 137 gossa.RegisterPackage("$PKGPATH",extMap$ID,typList$ID) 138 } 139 140 var extMap$ID = map[string]interface{}{$EXTMAP} 141 142 var typList$ID = []interface{}{$TYPLIST} 143 ` 144 145 var template_empty = `// export by github.com/goplus/gossa/cmd/qexp 146 147 $TAGS 148 149 package $PKGNAME 150 151 import ( 152 "github.com/goplus/gossa" 153 ) 154 155 func init() { 156 gossa.RegisterPackage("$PKGPATH",nil,nil) 157 } 158 ` 159 160 /* 161 type TypedConst struct { 162 Typ reflect.Type 163 Value constant.Value 164 } 165 166 type UntypedConst struct { 167 Typ string 168 Value constant.Value 169 } 170 171 type Package struct { 172 Name string 173 Path string 174 Types []reflect.Type 175 AliasTypes map[string]reflect.Type 176 Vars map[string]reflect.Value 177 Funcs map[string]reflect.Value 178 Methods map[string]reflect.Value 179 TypedConsts map[string]TypedConst 180 UntypedConsts map[string]UntypedConst 181 Deps map[string]string 182 } 183 */ 184 185 var template_pkg = `// export by github.com/goplus/gossa/cmd/qexp 186 187 $TAGS 188 189 package $PKGNAME 190 191 import ( 192 $IMPORTS 193 194 "github.com/goplus/gossa" 195 ) 196 197 func init() { 198 gossa.RegisterPackage(&gossa.Package { 199 Name: "$PKGNAME", 200 Path: "$PKGPATH", 201 Deps: map[string]string{$DEPS}, 202 Interfaces: map[string]reflect.Type{$INTERFACES}, 203 NamedTypes: map[string]gossa.NamedType{$NAMEDTYPES}, 204 AliasTypes: map[string]reflect.Type{$ALIASTYPES}, 205 Vars: map[string]reflect.Value{$VARS}, 206 Funcs: map[string]reflect.Value{$FUNCS}, 207 TypedConsts: map[string]gossa.TypedConst{$TYPEDCONSTS}, 208 UntypedConsts: map[string]gossa.UntypedConst{$UNTYPEDCONSTS}, 209 }) 210 } 211 `