Skip to content

Commit

Permalink
add generate-package-code
Browse files Browse the repository at this point in the history
  • Loading branch information
chyroc committed Jun 15, 2018
1 parent 9bd0532 commit efaebbe
Show file tree
Hide file tree
Showing 60 changed files with 2,319 additions and 621 deletions.
14 changes: 14 additions & 0 deletions cmd/generate-std-packages/convert.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package main

func convert(pkgImportName string, notTypes []pkgFuncType) []pkgFuncType {
switch pkgImportName {
case "math":
for k := range notTypes {
if notTypes[k].FuncTypeName == "MaxUint64" {
notTypes[k].Expr = "uint64(math.MaxUint64)"
}
}
}

return notTypes
}
28 changes: 28 additions & 0 deletions cmd/generate-std-packages/extra.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package main

type kv struct {
k string
v string
}
type extra struct {
detail string
packageImport []kv
packageTypesImport []kv
}

var extraList = map[string]extra{
"sort": {
detail: `// SortFuncsStruct provides functions to be used with Sort
type SortFuncsStruct struct {
LenFunc func() int
LessFunc func(i, j int) bool
SwapFunc func(i, j int)
}
func (s SortFuncsStruct) Len() int { return s.LenFunc() }
func (s SortFuncsStruct) Less(i, j int) bool { return s.LessFunc(i, j) }
func (s SortFuncsStruct) Swap(i, j int) { s.SwapFunc(i, j) }
`,
packageTypesImport: []kv{{"SortFuncsStruct", "&SortFuncsStruct{}"}},
},
}
105 changes: 105 additions & 0 deletions cmd/generate-std-packages/gen-package-scope/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package main

import (
"encoding/json"
"flag"
"fmt"
"go/importer"
"go/types"
"os"
"reflect"
"strings"
)

var packageName string

func init() {
flag.StringVar(&packageName, "package", "", "package name")
flag.Parse()
}

type pkgFuncType struct {
PkgName string `json:"pkg_name"`
FuncTypeName string `json:"func_type_name"`
Expr string `json:"expr"`
}

type output struct {
NotTypes []pkgFuncType `json:"not_types"`
TypeAssigns []pkgFuncType `json:"type_assigns"`
TypeVars []string `json:"type_vars"`
}

func getpackageTailName(packageImportName string) string {
n := strings.Split(packageImportName, "/")
return n[len(n)-1]
}

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

return n
}

var keyword = map[string]bool{
"interface": true,
"func": true,
"time": true,
"error": true,
"url": true,
"rand": true,
"flag": true,
"regexp": true,
"int": true,
}

func dealPackageScope(pkgImportName string) ([]pkgFuncType, []pkgFuncType, []string, error) {
pkg, err := importer.Default().Import(pkgImportName)
if err != nil {
return nil, nil, nil, err
}

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

for _, name := range scope.Names() {

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))
typeAssigns = append(typeAssigns, pkgFuncType{pkgImportName, name, fmt.Sprintf(`reflect.TypeOf(&%s).Elem()`, varName)})
default:
notTypes = append(notTypes, pkgFuncType{pkgImportName, name, getConvertedName(pkgImportName, name)})
}
}
}

return notTypes, typeAssigns, typeVars, nil
}

func main() {
if packageName == "" {
fmt.Fprint(os.Stderr, "package name is empty")
return
}
notTypes, typeAssigns, typeVars, err := dealPackageScope(packageName)
if err != nil {
fmt.Fprint(os.Stderr, err)
return
}

b, err := json.MarshalIndent(output{notTypes, typeAssigns, typeVars}, "", " ")
if err != nil {
fmt.Fprint(os.Stderr, err)
return
}
fmt.Printf("%s", b)
}
72 changes: 72 additions & 0 deletions cmd/generate-std-packages/helper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package main

import (
"fmt"
"strings"
)

type pkgFuncType struct {
PkgName string `json:"pkg_name"`
FuncTypeName string `json:"func_type_name"`
Expr string `json:"expr"`
}

type output struct {
NotTypes []pkgFuncType `json:"not_types"`
TypeAssigns []pkgFuncType `json:"type_assigns"`
TypeVars []string `json:"type_vars"`
}

func goVersionToBuildTagName(s string) string {
s = goVersionToFileExtName(s)
return fmt.Sprintf("%s.%s", s[:1], s[1:])
}

func goVersionToFileExtName(s string) string {
return strings.Replace(strings.ToLower(s), "go", "", -1)
}

func genFileName(pkg, ext string) string {
f := "packages/" + strings.Join(strings.Split(pkg, "/"), ".")
if ext == "" {
return f + ".go"
} else {
return f + "." + ext + ".go"
}
}

func diffSlice(notTypes1, typeAssigns1 []pkgFuncType, typeVars1 []string, notTypes2, typeAssigns2 []pkgFuncType, typeVars2 []string) ([]pkgFuncType, []pkgFuncType, []string) {
var diffPkgFuncTypeSlice = func(a, b []pkgFuncType) []pkgFuncType {
var m = make(map[pkgFuncType]bool)
for _, v := range b {
m[v] = true
}

var d []pkgFuncType
for _, v := range a {
if !m[v] {
d = append(d, v)
}
}
return d
}
var diffStringSlice = func(a, b []string) []string {
var m = make(map[string]bool)
for _, v := range b {
m[v] = true
}

var d []string
for _, v := range a {
if !m[v] {
d = append(d, v)
}
}
return d
}

notTypesDiff := diffPkgFuncTypeSlice(notTypes1, notTypes2)
typeAssignsDiff := diffPkgFuncTypeSlice(typeAssigns1, typeAssigns2)
typeVarsDiff := diffStringSlice(typeVars1, typeVars2)
return notTypesDiff, typeAssignsDiff, typeVarsDiff
}
Loading

0 comments on commit efaebbe

Please sign in to comment.