diff --git a/cmd/xcode/main.go b/cmd/xcode/main.go index 01f1af0..fe1117c 100644 --- a/cmd/xcode/main.go +++ b/cmd/xcode/main.go @@ -1,31 +1,25 @@ package main import ( - "bytes" "flag" "fmt" - "go/ast" - "go/format" - "go/parser" - "go/token" + "github.com/donutloop/toolkit/internal/ast" "io/ioutil" "log" "os" - "strings" "text/tabwriter" - "github.com/fatih/astrewrite" ) func main() { - log.SetFlags(log.Ldate | log.Lshortfile | log.Ltime) + log.SetFlags(0) fs := flag.NewFlagSet("xcode", flag.ExitOnError) var ( - in = fs.String("in", "", "input file") - out = fs.String("out", "", "output file") - pkg = fs.String("pkg", "", "package name") - typ = fs.String("type", "", "type") - mode = fs.String("mode", "", "activate mode") + in = fs.String("in", "", "input file") + out = fs.String("out", "", "output file") + pkg = fs.String("pkg", "", "package name") + typ = fs.String("type", "", "type") + mode = fs.String("mode", "", "activate mode") ) fs.Usage = usageFor(fs, "xcode [flags]") fs.Parse(os.Args[1:]) @@ -51,10 +45,10 @@ func main() { log.Fatalf("could not read file (%v)", err) } - rnFunc := RenamePackage(*pkg) - ctFunc := ChangeType("GenericType", *typ, *mode) + rnFunc := ast.RenamePackage(*pkg) + ctFunc := ast.ChangeType("GenericType", *typ, *mode) - modifiedFile, err := modifyAst(inputFile, rnFunc, ctFunc) + modifiedFile, err := ast.ModifyAst(inputFile, rnFunc, ctFunc) if err != nil { log.Fatalf("could not modify ast of file (%v)", err) } @@ -64,73 +58,6 @@ func main() { } } -const ( - DebugMode string = "DEV" -) - -func RenamePackage(packageName string) func(file *ast.File) *ast.File { - return func(file *ast.File) *ast.File { - file.Name = &ast.Ident{Name: packageName} - return file - } -} - -func ChangeType(typeName string, newType string, debugMode string) func(file *ast.File) *ast.File { - return func(file *ast.File) *ast.File { - rewriteFunc := func(n ast.Node) (ast.Node, bool) { - switch x := n.(type) { - case *ast.Ident: - if typeName == x.Name { - x = &ast.Ident{Name: newType} - } - return x, true - case *ast.CallExpr: - for i := 0; i < len(x.Args); i++ { - v, ok := x.Args[i].(*ast.Ident) - if ok { - if strings.ToLower(typeName) == strings.ToLower(v.Name) { - x.Args[i] = &ast.Ident{Name: fmt.Sprintf("%s.(%s)", v.Name, newType)} - } - } - } - return x, true - default: - if debugMode == DebugMode { - log.SetFlags(0) - log.Println("ast node:") - log.Println(fmt.Sprintf("verbose value: %#v", x)) - log.Println(fmt.Sprintf("type: %T", x)) - log.Println(fmt.Sprintf("value: %v", x)) - } - } - return n, true - } - - astrewrite.Walk(file, rewriteFunc) - - return file - } -} - -func modifyAst(dest []byte, fns ...func(*ast.File) *ast.File) ([]byte, error) { - destFset := token.NewFileSet() - destF, err := parser.ParseFile(destFset, "", dest, 0) - if err != nil { - return nil, err - } - - for _, fn := range fns { - destF = fn(destF) - } - - var buf bytes.Buffer - if err := format.Node(&buf, destFset, destF); err != nil { - return nil, fmt.Errorf("couldn't format package code (%v)", err) - } - - return buf.Bytes(), nil -} - func usageFor(fs *flag.FlagSet, short string) func() { return func() { fmt.Fprintf(os.Stdout, "USAGE\n") @@ -139,7 +66,7 @@ func usageFor(fs *flag.FlagSet, short string) func() { fmt.Fprintf(os.Stdout, "FLAGS\n") tw := tabwriter.NewWriter(os.Stdout, 0, 2, 2, ' ', 0) fs.VisitAll(func(f *flag.Flag) { - if f.Name == "mode" { + if f.Name == "debug" { return } def := f.DefValue @@ -151,4 +78,3 @@ func usageFor(fs *flag.FlagSet, short string) func() { tw.Flush() } } - diff --git a/internal/ast/ast.go b/internal/ast/ast.go new file mode 100644 index 0000000..698f1bb --- /dev/null +++ b/internal/ast/ast.go @@ -0,0 +1,79 @@ +package ast + +import ( + "bytes" + "fmt" + "github.com/fatih/astrewrite" + "go/ast" + "go/format" + "go/parser" + "go/token" + "log" + "strings" +) + +const ( + DebugMode string = "DEV" +) + +func RenamePackage(packageName string) func(file *ast.File) *ast.File { + return func(file *ast.File) *ast.File { + file.Name = &ast.Ident{Name: packageName} + return file + } +} + +func ChangeType(typeName string, newType string, debugMode string) func(file *ast.File) *ast.File { + return func(file *ast.File) *ast.File { + rewriteFunc := func(n ast.Node) (ast.Node, bool) { + switch x := n.(type) { + case *ast.Ident: + if typeName == x.Name { + x = &ast.Ident{Name: newType} + } + return x, true + case *ast.CallExpr: + for i := 0; i < len(x.Args); i++ { + v, ok := x.Args[i].(*ast.Ident) + if ok { + if strings.ToLower(typeName) == strings.ToLower(v.Name) { + x.Args[i] = &ast.Ident{Name: fmt.Sprintf("%s.(%s)", v.Name, newType)} + } + } + } + return x, true + default: + if debugMode == DebugMode { + log.Println("ast node:") + log.Println(fmt.Sprintf("verbose value: %#v", x)) + log.Println(fmt.Sprintf("type: %T", x)) + log.Println(fmt.Sprintf("value: %v", x)) + } + } + return n, true + } + + astrewrite.Walk(file, rewriteFunc) + + return file + } +} + +func ModifyAst(dest []byte, fns ...func(*ast.File) *ast.File) ([]byte, error) { + destFset := token.NewFileSet() + destF, err := parser.ParseFile(destFset, "", dest, 0) + if err != nil { + return nil, err + } + + for _, fn := range fns { + destF = fn(destF) + } + + var buf bytes.Buffer + if err := format.Node(&buf, destFset, destF); err != nil { + return nil, fmt.Errorf("couldn't format package code (%v)", err) + } + + return buf.Bytes(), nil +} diff --git a/worker/doc_test.go b/worker/doc_test.go index 8e137f6..2bcc741 100644 --- a/worker/doc_test.go +++ b/worker/doc_test.go @@ -15,7 +15,7 @@ func ExampleWorker() { queue := worker.New(2, workerHandler, 10) queue <- "hello" - <- time.After(time.Millisecond * 250) + <-time.After(time.Millisecond * 250) // Output: hello } diff --git a/worker/worker.go b/worker/worker.go index 3da19c1..ff2038b 100644 --- a/worker/worker.go +++ b/worker/worker.go @@ -5,11 +5,11 @@ import ( ) type worker struct { - c chan interface{} + c chan interface{} done chan bool jobs chan interface{} - fn func(n GenericType) - buf *list.List + fn func(n GenericType) + buf *list.List } // NewWorker starts n*Workers goroutines running func on incoming @@ -17,11 +17,11 @@ type worker struct { func New(nWorkers uint, fn func(gt GenericType), buffer uint) chan<- interface{} { retc := make(chan interface{}, buffer) w := &worker{ - c: retc, + c: retc, jobs: make(chan interface{}, buffer), done: make(chan bool), - fn: fn, - buf: list.New(), + fn: fn, + buf: list.New(), } go w.listener() for i := uint(0); i < nWorkers; i++ { diff --git a/worker/worker_test.go b/worker/worker_test.go index 9cc0575..c58ff34 100644 --- a/worker/worker_test.go +++ b/worker/worker_test.go @@ -26,7 +26,7 @@ func TestWorker(t *testing.T) { return } - if !containes([]string{"hello", "golang", "world"}, v) { + if !containes([]string{"hello", "golang", "world"}, v) { t.Errorf("value is bad got=%v", parameter) } @@ -40,7 +40,7 @@ func TestWorker(t *testing.T) { queue <- "golang" queue <- "world" - <- time.After(500 * time.Millisecond) + <-time.After(500 * time.Millisecond) if atomic.LoadInt32(&counter) != 3 { t.Errorf("counter is bad (want=3, got=%v)", atomic.LoadInt32(&counter)) diff --git a/worker/worker_type.go b/worker/worker_type.go index 6146325..dad1cdf 100644 --- a/worker/worker_type.go +++ b/worker/worker_type.go @@ -1,5 +1,4 @@ package worker // used for code generation replacing -type GenericType interface {} - +type GenericType interface{}