Skip to content

Commit

Permalink
remove extra spaces and fix bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
chyroc committed Apr 9, 2018
1 parent 56a5ee5 commit 4f7d68f
Show file tree
Hide file tree
Showing 44 changed files with 264 additions and 270 deletions.
269 changes: 84 additions & 185 deletions cmd/generate-std-packages/main.go
Original file line number Diff line number Diff line change
@@ -1,64 +1,39 @@
package main

import (
"bytes"
"fmt"
"go/importer"
"go/types"
"io/ioutil"
"log"
"reflect"
"strings"
"text/template"
)

func parseTmpl(tmpl string, data map[string]interface{}) ([]byte, error) {
parsedTmpl, err := template.New("tmpl").Parse(tmpl)
if err != nil {
return nil, err
}

var result bytes.Buffer
if err := parsedTmpl.Execute(&result, data); err != nil {
return nil, err
}

return result.Bytes(), nil
type pkgFuncType struct {
PkgName string `json:"pkg_name"`
FuncTypeName string `json:"func_type_name"`
Expr string `json:"expr"`
}

func generatePackageImportCode18(pkgImportName string) ([]byte, error) {
var pkgTmpl = `package packages
import (
{{.import_packages}}
)
{{.extra}}
func init() {
{{.package_no_struct_types}}
Packages["{{.name}}"] = map[string]interface{}{
{{.package_funcs}}
}
PackageTypes["{{.name}}"] = map[string]interface{}{
{{.package_types}}
}
{{.import_multi_version_call}}
}
`
func dealPackageScope(pkgImportName string, goVersion version) ([]pkgFuncType, []pkgFuncType, []string) {
pkg, err := importer.Default().Import(pkgImportName)
if err != nil {
return nil, err
log.Fatal(err)
}

var scope = pkg.Scope()
var funcOrVars []string
var typs []string
var notTypes []pkgFuncType
var typeAssigns []pkgFuncType
var typeVars []string
var importPackages []string
var scope = pkg.Scope()

for _, name := range scope.Names() {
if include(pkgImportName, name, black) || include(pkgImportName, name, in19) || include(pkgImportName, name, in110) {
if include(pkgImportName, name, black) {
continue
}
if goVersion.isGeneral() && (include(pkgImportName, name, in19) || include(pkgImportName, name, in110)) {
continue
} else if (goVersion.is19() && !include(pkgImportName, name, in19)) || (goVersion.is110() && !include(pkgImportName, name, in110)) {
continue
}

Expand All @@ -71,179 +46,93 @@ func init() {
varName = varName + "_"
}
typeVars = append(typeVars, fmt.Sprintf(` var %s %s.%s`, varName, getpackageTailName(pkgImportName), name))
typs = append(typs, fmt.Sprintf(` "%s": reflect.TypeOf(&%s).Elem(),`, name, varName))
typeAssigns = append(typeAssigns, pkgFuncType{pkgImportName, name, fmt.Sprintf(`reflect.TypeOf(&%s).Elem()`, varName)})
default:
funcOrVars = append(funcOrVars, fmt.Sprintf(` "%s": %s.%s,`, name, getpackageTailName(pkgImportName), name))
notTypes = append(notTypes, pkgFuncType{pkgImportName, name, getConvertedName(pkgImportName, name)})
}
}
}

return notTypes, typeAssigns, typeVars
}

func dealExtra(pkgImportName string, goVersion version) (string, []pkgFuncType, []pkgFuncType) {
var extraDetail string
var notTypes []pkgFuncType
var typeAssigns []pkgFuncType

if extra, ok := extraList[pkgImportName]; ok {
extraDetail = extra.detail
if extra.packageImport != nil {
for _, v := range extra.packageImport {
funcOrVars = append(funcOrVars, fmt.Sprintf(` "%s": "%s",`, v.k, v.v))
if goVersion.isGeneral() {
extraDetail = extra.detail
if extra.packageImport != nil {
for _, v := range extra.packageImport {
notTypes = append(notTypes, pkgFuncType{pkgImportName, v.k, v.v})
}
}
if extra.packageTypesImport != nil {
for _, v := range extra.packageTypesImport {
typeAssigns = append(typeAssigns, pkgFuncType{pkgImportName, v.k, v.v})
}
}
}
if extra.packageTypesImport != nil {
for _, v := range extra.packageTypesImport {
typs = append(typs, fmt.Sprintf(` "%s": %s,`, v.k, v.v))
if goVersion.is18() {
extraDetail = extra.detail
if extra.packageImport != nil {
for _, v := range extra.packageImport {
notTypes = append(notTypes, pkgFuncType{pkgImportName, v.k, v.v})
}
}
if extra.packageTypesImport != nil {
for _, v := range extra.packageTypesImport {
typeAssigns = append(typeAssigns, pkgFuncType{pkgImportName, v.k, v.v})
}
}
}
} else {
pkgTmpl = strings.Replace(pkgTmpl, "{{.extra}}", "", -1)

}

importPackages = append(importPackages, fmt.Sprintf(`"%s"`, pkgImportName))
return extraDetail, notTypes, typeAssigns
}

func generatePackageImportCodeAll(pkgImportName string, goVersion version) ([]byte, error) {
notTypes, typeAssigns, typeVars := dealPackageScope(pkgImportName, goVersion)
extraDetail, notTypes2, typeAssigns2 := dealExtra(pkgImportName, goVersion)

notTypes = append(notTypes, notTypes2...)
typeAssigns = append(typeAssigns, typeAssigns2...)

var importPackages = []string{fmt.Sprintf(`"%s"`, pkgImportName)}
if len(typeVars) > 0 {
importPackages = append(importPackages, `"reflect"`)
} else {
pkgTmpl = strings.Replace(pkgTmpl, "{{.package_no_struct_types}}\n", "", -1)
}

if len(typs) == 0 {
pkgTmpl = strings.Replace(pkgTmpl, "\n PackageTypes[\"{{.name}}\"] = map[string]interface{}{\n{{.package_type}}\n }", "", -1)
}

var importMultiVersionCall string
if v, ok := ruleList[pkgImportName]; ok && (v.in19 != nil || v.in110 != nil) {
if v, ok := ruleList[pkgImportName]; ok && goVersion.isGeneral() && (v.in19 != nil || v.in110 != nil) {
importMultiVersionCall += getPackageInitName(pkgImportName) + "()\n"
build := "// +build go1.8"
if v.in19 != nil {
build += ",!go1.9,!go1.10"
} else if v.in110 != nil {
build += ",!go1.10"
}
if err = ioutil.WriteFile(go18.filename(pkgImportName), []byte(build+"\n\npackage packages\n\nfunc "+getPackageInitName(pkgImportName)+"() { }\n"), 0644); err != nil {
log.Fatal(err)
}
} else {
pkgTmpl = strings.Replace(pkgTmpl, "{{.import_multi_version_call}}", "", -1)
}

var pkgTmpl = pkgExtraTmpl
if goVersion == gogo {
pkgTmpl = pkgNormalTmpl
}

return parseTmpl(pkgTmpl, map[string]interface{}{
"build_tag": goVersion.buildTag(),
"name": pkgImportName,
"package_funcs": strings.Join(funcOrVars, "\n"),
"package_types": strings.Join(typs, "\n"),
"package_funcs": notTypes,
"package_types": typeAssigns,
"package_no_struct_types": strings.Join(typeVars, "\n"),
"import_packages": strings.Join(importPackages, "\n"),
"extra": extraDetail,
"import_func_name": getPackageInitName(pkgImportName),
"import_multi_version_call": importMultiVersionCall,
})
}

func generatePackageImportCode18Plus(pkgImportName string, goVersion version) ([]byte, error) {
var pkgTmpl = `
{{.build_tag}}
package packages
import (
{{.import_packages}}
)
{{.extra}}
func {{.import_func_name}}() {
{{.package_no_struct_types}}
{{range $index, $element := .package_funcs}}
Packages["{{.PkgName}}"]["{{.FuncTypeName}}"] = {{.Expr}}
{{end}}
{{range $index, $element := .package_types}}
PackageTypes["{{.PkgName}}"]["{{.FuncTypeName}}"] = {{.Expr}}
{{end}}
}
`

type pkgFuncType struct {
PkgName string `json:"pkg_name"`
FuncTypeName string `json:"func_type_name"`
Expr string `json:"expr"`
}
pkg, err := importer.Default().Import(pkgImportName)
if err != nil {
return nil, err
}

var scope = pkg.Scope()
var funcOrVars []pkgFuncType
var typs []pkgFuncType
var typeVars []string
var importPackages []string

for _, name := range scope.Names() {
if include(pkgImportName, name, black) {
continue
} else if goVersion.is18plus() && !include(pkgImportName, name, in19) {
continue
} else if goVersion.is110() && !include(pkgImportName, name, in110) {
continue
}

sc := scope.Lookup(name)
if sc.Exported() {
switch reflect.TypeOf(sc) {
case reflect.TypeOf(new(types.TypeName)):
varName := strings.ToLower(name)
if keyword[varName] {
varName = varName + "_"
}
typeVars = append(typeVars, fmt.Sprintf(` var %s %s.%s`, varName, getpackageTailName(pkgImportName), name))
typs = append(typs, pkgFuncType{pkgImportName, name, fmt.Sprintf(`reflect.TypeOf(&%s).Elem()`, varName)})
default:
funcOrVars = append(funcOrVars, pkgFuncType{pkgImportName, name, getpackageTailName(pkgImportName) + "." + name})
}
}
}

var extraDetail string
if extra, ok := extraList[pkgImportName]; goVersion.is18() && ok {
extraDetail = extra.detail
if extra.packageImport != nil {
for _, v := range extra.packageImport {
funcOrVars = append(funcOrVars, pkgFuncType{pkgImportName, v.k, v.v})
}
}
if extra.packageTypesImport != nil {
for _, v := range extra.packageTypesImport {
typs = append(typs, pkgFuncType{pkgImportName, v.k, v.v})
}
}
} else {
pkgTmpl = strings.Replace(pkgTmpl, "{{.extra}}", "", -1)
}

importPackages = append(importPackages, fmt.Sprintf(`"%s"`, pkgImportName))
if len(typeVars) > 0 {
importPackages = append(importPackages, `"reflect"`)
} else {
pkgTmpl = strings.Replace(pkgTmpl, "{{.package_no_struct_types}}\n", "", -1)
}

return parseTmpl(pkgTmpl, map[string]interface{}{
"build_tag": goVersion.buildTag(),
"name": pkgImportName,
"package_funcs": funcOrVars,
"package_types": typs,
"package_no_struct_types": strings.Join(typeVars, "\n"),
"import_packages": strings.Join(importPackages, "\n"),
"extra": extraDetail,
"import_func_name": getPackageInitName(pkgImportName),
})
}

func runOneVersion(pkgImportName string, goVersion version) {
var result []byte
var err error
if goVersion == gogo {
if result, err = generatePackageImportCode18(pkgImportName); err != nil {
log.Fatal(err)
}
} else {
if result, err = generatePackageImportCode18Plus(pkgImportName, goVersion); err != nil {
log.Fatal(err)
}
result, err := generatePackageImportCodeAll(pkgImportName, goVersion)
if err != nil {
log.Fatal(err)
}

if err = ioutil.WriteFile(goVersion.filename(pkgImportName), result, 0644); err != nil {
Expand All @@ -253,15 +142,25 @@ func runOneVersion(pkgImportName string, goVersion version) {

func run(pkgImportName string) {
if v, ok := ruleList[pkgImportName]; ok {
build := "// +build "

if v.in19 != nil {
runOneVersion(pkgImportName, go18plus)
build += "!go1.9"
runOneVersion(pkgImportName, go19) // generate pkg.19.go
}
if v.in110 != nil {
runOneVersion(pkgImportName, go110)
build += "!go1.10"
runOneVersion(pkgImportName, go110) // generate pkg.110.go
}
if build != "// +build " {
// generate pkg.18.go
if err := ioutil.WriteFile(go18.filename(pkgImportName), []byte(build+"\n\npackage packages\n\nfunc "+getPackageInitName(pkgImportName)+"() { }\n"), 0644); err != nil {
log.Fatal(err)
}
}
}

runOneVersion(pkgImportName, gogo)
runOneVersion(pkgImportName, gogo) // generate pkg.go and
}

func main() {
Expand Down
31 changes: 27 additions & 4 deletions cmd/generate-std-packages/rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@ var keyword = map[string]bool{
"int": true,
}

type convertFunc func(string) string

type rule struct {
in19 []string // not in 18
in110 []string // not in 18 and 19
black []string
in19 []string // not in 18
in110 []string // not in 18 and 19
black []string
convert map[string]convertFunc
}

var ruleList = map[string]rule{
Expand All @@ -30,7 +33,9 @@ var ruleList = map[string]rule{
},
"math": {
in110: []string{"Erfcinv", "Erfinv", "Round", "RoundToEven"},
black: []string{"MaxUint64"},
convert: map[string]convertFunc{"MaxUint64": func(s string) string {
return "uint64(math.MaxUint64)"
}},
},
"math/rand": {
in110: []string{"Shuffle"},
Expand Down Expand Up @@ -78,3 +83,21 @@ func include(packageName, item, typ string) bool {

return false
}

func getConvertedName(pkgImportName, name string) string {
n := getpackageTailName(pkgImportName) + "." + name

rule, ok := ruleList[pkgImportName]
if !ok {
return n
} else if rule.convert == nil {
return n
}

f, ok := rule.convert[name]
if !ok {
return n
}

return f(name)
}
Loading

0 comments on commit 4f7d68f

Please sign in to comment.