Created
January 3, 2020 03:51
-
-
Save spikeekips/df9913f40abf9afbd9322693ee1c1fdb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"go/ast" | |
"go/importer" | |
"go/parser" | |
"go/token" | |
"go/types" | |
"os" | |
"path/filepath" | |
"strings" | |
"github.com/rs/zerolog" | |
"github.com/spf13/cobra" | |
"github.com/spikeekips/mitum/cmd" | |
) | |
var ( | |
log zerolog.Logger | |
packageCache map[string]string | |
basePackageName string | |
) | |
var rootCmd = &cobra.Command{ | |
Use: "mitum-codegen-hinted [<key> ...]", | |
Short: "generate code for hinted", | |
PersistentPreRun: func(c *cobra.Command, args []string) { | |
if l, err := cmd.LoadLogging(); err != nil { | |
c.Println("Error:", err.Error()) | |
os.Exit(1) | |
} else { | |
log = l | |
} | |
log.Debug(). | |
RawJSON("flags", cmd.PrintFlagsJSON(c)). | |
Msg("parsed flags") | |
packageCache = map[string]string{} | |
}, | |
Run: func(c *cobra.Command, args []string) { | |
dir, err := os.Getwd() | |
if err != nil { | |
c.Println("Error:", err.Error()) | |
os.Exit(1) | |
} | |
/* | |
pkgs, err := listPackages(dir) | |
if err != nil { | |
c.Println("Error:", err.Error()) | |
os.Exit(1) | |
} | |
log.Info().Msgf("found %d packages", len(pkgs)) | |
for _, pkg := range pkgs { | |
for name, f := range pkg.Files { | |
log_ := log.With().Str("package", pkg.Name).Str("file", name).Logger() | |
log_.Debug().Msg("dig in package") | |
if f.Scope == nil { | |
continue | |
} | |
log_.Debug().Int("objects", len(f.Scope.Objects)).Msg("objects found") | |
for _, obj := range f.Scope.Objects { | |
if obj.Kind != ast.Typ { | |
continue | |
} | |
log_.Debug().Str("struct", obj.Name).Msg("struct found") | |
} | |
} | |
ast.Inspect(pkg, func(n ast.Node) bool { | |
log_ := log.With().Str("package", pkg.Name).Logger() | |
switch t := n.(type) { | |
// find variable declarations | |
case *ast.TypeSpec: | |
if t.Name.IsExported() { | |
switch t.Type.(type) { | |
case *ast.StructType: | |
log_.Debug().Str("struct", t.Name.Name).Msg("struct found") | |
if pkg.Scope == nil { | |
return true | |
} | |
fmt.Println("..", t.Name.Name, pkg.Scope == nil) | |
fmt.Println(">", pkg.Scope.Lookup(t.Name.Name)) | |
} | |
} | |
} | |
return true | |
}) | |
} | |
*/ | |
listPackages(c, dir) | |
}, | |
} | |
func listPackages(c *cobra.Command, dir string) (map[string]*ast.Package, error) { | |
/* | |
pkgs := map[string]*ast.Package{} | |
if fd, err := os.Open(dir); err != nil { | |
return nil, err | |
} else if list, err := fd.Readdir(-1); err != nil { | |
return nil, err | |
} else { | |
for _, fi := range list { | |
if !fi.IsDir() { | |
continue | |
} else if strings.HasPrefix(fi.Name(), ".") { | |
continue | |
} | |
ps, err := parser.ParseDir(token.NewFileSet(), fi.Name(), filter, 0) | |
if err != nil { | |
return nil, err | |
} else if len(ps) < 1 { | |
continue | |
} | |
for name, pkg := range ps { | |
pkgs[name] = pkg | |
log.Debug().Str("name", name).Int("files", len(pkg.Files)).Msg("found package") | |
} | |
} | |
} | |
return pkgs, nil | |
*/ | |
fileSet := token.NewFileSet() | |
var pkgs []*ast.Package | |
if fd, err := os.Open(dir); err != nil { | |
return nil, err | |
} else if list, err := fd.Readdir(-1); err != nil { | |
return nil, err | |
} else { | |
for _, fi := range list { | |
if !fi.IsDir() { | |
continue | |
} else if strings.HasPrefix(fi.Name(), ".") { | |
continue | |
} | |
ps, err := parser.ParseDir(fileSet, filepath.Join(dir, fi.Name()), filter, 0) | |
if err != nil { | |
return nil, err | |
} else if len(ps) < 1 { | |
continue | |
} | |
for _, pkg := range ps { | |
pkgs = append(pkgs, pkg) | |
} | |
} | |
} | |
var files []*ast.File | |
for _, pkg := range pkgs { | |
for _, f := range pkg.Files { | |
files = append(files, f) | |
} | |
} | |
for _, pkg := range pkgs { | |
var pkgPath string | |
for name, _ := range pkg.Files { | |
pkgPath = filepath.Dir(name) | |
break | |
} | |
if err := parsePackage(c, pkgPath, fileSet, pkg, files); err != nil { | |
return nil, err | |
} | |
} | |
return nil, nil | |
} | |
func parsePackage(c *cobra.Command, dir string, fileSet *token.FileSet, pkg *ast.Package, _ []*ast.File) error { | |
var files []*ast.File | |
for _, f := range pkg.Files { | |
files = append(files, f) | |
} | |
fmt.Println(">", dir, pkg.Name) | |
config := &types.Config{ | |
Error: func(err error) { | |
log.Error().Err(err).Msg("problem found in types.Config()") | |
}, | |
Importer: importer.Default(), | |
} | |
pg, err := config.Check(dir, fileSet, files, nil) | |
if err != nil { | |
return err | |
} | |
fmt.Println("<", pg.Name()) | |
return nil | |
} | |
func filter(info os.FileInfo) bool { | |
name := info.Name() | |
if info.IsDir() { | |
return false | |
} | |
if filepath.Ext(name) != ".go" { | |
return false | |
} | |
if strings.HasSuffix(name, "_test.go") { | |
return false | |
} | |
return true | |
} | |
func main() { | |
rootCmd.PersistentFlags().Var(&cmd.FlagLogLevel, "log-level", "log level: {debug error warn info crit}") | |
rootCmd.PersistentFlags().StringVar(&cmd.FlagLogOut, "log", cmd.FlagLogOut, "log output directory") | |
rootCmd.PersistentFlags().Var(&cmd.FlagLogFormat, "log-format", "log format: {json terminal}") | |
if err := rootCmd.Execute(); err != nil { | |
rootCmd.Println("Error:", err.Error()) | |
os.Exit(1) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment