refactor: goexports use go template.

This commit is contained in:
Fernandez Ludovic
2019-01-07 23:46:36 +01:00
parent 3bf45a4b32
commit 45893a87a8
2 changed files with 75 additions and 52 deletions

View File

@@ -1,36 +1,57 @@
// This program generates code to register binary program symbols to
// the interpeter.
// This program generates code to register binary program symbols to the interpreter.
// See stdlib.go for usage
package main
import (
"bufio"
"fmt"
"bytes"
"go/format"
"go/importer"
"go/types"
"io/ioutil"
"log"
"os"
"os/exec"
"path"
"strings"
"text/template"
"unicode"
)
func genfile(dest, pkgName, ofile string) error {
const model = `package {{ .Dest }}
// CODE GENERATED AUTOMATICALLY BY 'goexports {{ .PkgName }}'.
// THIS FILE MUST NOT BE EDITED.
import (
"{{ .PkgName }}"
"reflect"
)
func init() {
Value["{{ .PkgName }}"] = map[string]reflect.Value{
{{range .Val -}}
{{if forceUint $.Pkg . -}}
"{{.}}": reflect.ValueOf(uint({{ $.Pkg }}.{{.}})),
{{else -}}
"{{.}}": reflect.ValueOf({{ $.Pkg }}.{{.}}),
{{ end -}}
{{end -}}
}
Type["{{ .PkgName }}"] = map[string]reflect.Type{
{{range .Typ -}}
"{{.}}": reflect.TypeOf((*{{ $.Pkg }}.{{.}})(nil)).Elem(),
{{end -}}
}
}
`
func genContent(dest, pkgName string) ([]byte, error) {
p, err := importer.Default().Import(pkgName)
if err != nil {
return err
return nil, err
}
f, err := os.Create(ofile)
if err != nil {
return err
}
defer f.Close()
out := bufio.NewWriter(f)
var typ []string
var val []string
sc := p.Scope()
@@ -49,43 +70,43 @@ func genfile(dest, pkgName, ofile string) error {
}
}
pkg := path.Base(pkgName)
base := template.New("goexports")
base.Funcs(template.FuncMap{
"forceUint": forceUint,
})
// Print header
fmt.Fprintln(out, `package `+dest+`
// Code generated by 'goexports `+pkgName+`'. DO NOT EDIT.
import (
"`+pkgName+`"
"reflect"
)
func init() {`)
// Print values
fmt.Fprintln(out, `Value["`+pkgName+`"] = map[string]reflect.Value{`)
for _, v := range val {
if (pkgName == "math" && v == "MaxUint64") ||
(pkgName == "hash/crc64" && v == "ECMA") ||
(pkgName == "hash/crc64" && v == "ISO") {
// go build will fail with overflow error if this const is untyped. Fix this.
fmt.Fprintln(out, "\""+v+"\": reflect.ValueOf(uint("+pkg+"."+v+")),")
} else {
fmt.Fprintln(out, "\""+v+"\": reflect.ValueOf("+pkg+"."+v+"),")
}
parse, err := base.Parse(model)
if err != nil {
return nil, err
}
fmt.Fprintln(out, "}")
// Print types
fmt.Fprintln(out, `Type["`+pkgName+`"] = map[string]reflect.Type{`)
for _, t := range typ {
fmt.Fprintln(out, `"`+t+`": reflect.TypeOf((*`+pkg+"."+t+")(nil)).Elem(),")
data := map[string]interface{}{
"Dest": dest,
"PkgName": pkgName,
"Pkg": path.Base(pkgName),
"Val": val,
"Typ": typ,
}
fmt.Fprintln(out, "}")
fmt.Fprintln(out, "}")
b := &bytes.Buffer{}
err = parse.Execute(b, data)
if err != nil {
return nil, err
}
return out.Flush()
// gofmt
source, err := format.Source(b.Bytes())
if err != nil {
return nil, err
}
return source, nil
}
// go build will fail with overflow error if this const is untyped. Fix this.
func forceUint(pkgName, v string) bool {
return (pkgName == "math" && v == "MaxUint64") ||
(pkgName == "hash/crc64" && v == "ECMA") ||
(pkgName == "hash/crc64" && v == "ISO")
}
func main() {
@@ -96,15 +117,15 @@ func main() {
dest := path.Base(dir)
for _, pkg := range os.Args[1:] {
oFile := strings.Replace(pkg, "/", "_", -1) + ".go"
if err := genfile(dest, pkg, oFile); err != nil {
content, err := genContent(dest, pkg)
if err != nil {
log.Fatal(err)
}
cmd := exec.Command("gofmt", "-w", oFile)
output, err := cmd.CombinedOutput()
oFile := strings.Replace(pkg, "/", "_", -1) + ".go"
err = ioutil.WriteFile(oFile, content, 0666)
if err != nil {
log.Println(output)
log.Fatal(err)
}
}

View File

@@ -1,6 +1,7 @@
package stdlib
// Code generated by 'goexports syscall'. DO NOT EDIT.
// CODE GENERATED AUTOMATICALLY BY 'goexports syscall'.
// THIS FILE MUST NOT BE EDITED.
import (
"reflect"
@@ -2116,6 +2117,7 @@ func init() {
"Write": reflect.ValueOf(syscall.Write),
"XCASE": reflect.ValueOf(syscall.XCASE),
}
Type["syscall"] = map[string]reflect.Type{
"Cmsghdr": reflect.TypeOf((*syscall.Cmsghdr)(nil)).Elem(),
"Conn": reflect.TypeOf((*syscall.Conn)(nil)).Elem(),