Skip to content

Commit

Permalink
restructured packages
Browse files Browse the repository at this point in the history
  • Loading branch information
donutloop committed Nov 25, 2018
1 parent 3e89c75 commit 46b46f7
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 96 deletions.
96 changes: 11 additions & 85 deletions cmd/xcode/main.go
Original file line number Diff line number Diff line change
@@ -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:])
Expand All @@ -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)
}
Expand All @@ -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")
Expand All @@ -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
Expand All @@ -151,4 +78,3 @@ func usageFor(fs *flag.FlagSet, short string) func() {
tw.Flush()
}
}

79 changes: 79 additions & 0 deletions internal/ast/ast.go
Original file line number Diff line number Diff line change
@@ -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
}
2 changes: 1 addition & 1 deletion worker/doc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
12 changes: 6 additions & 6 deletions worker/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,23 @@ 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
// parameters sent on the returned channel.
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++ {
Expand Down
4 changes: 2 additions & 2 deletions worker/worker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand All @@ -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))
Expand Down
3 changes: 1 addition & 2 deletions worker/worker_type.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
package worker

// used for code generation replacing
type GenericType interface {}

type GenericType interface{}

0 comments on commit 46b46f7

Please sign in to comment.