Ejemplo n.º 1
0
func main() {
	flag.Parse()
	if opts.pkg == "" {
		oops("-package should not be empty")
	}
	pk, err := build.Default.Import(opts.pkg, "", 0)
	if err != nil {
		log.Fatalln(err.Error())
	}
	if opts.targetDir == "" {
		opts.targetDir = pk.Dir
	}
	if opts.w {
		err := os.MkdirAll(opts.targetDir, 0777)
		if err != nil {
			log.Fatalln(err.Error())
		}
	}
	// Build the inline map.
	im := map[string]goinline.Target{}
	for _, s := range flag.Args() {
		k, v, err := goinline.ParseTarget(s)
		if err != nil {
			oops(err.Error())
		}
		if old, ok := im[k]; ok {
			oops(fmt.Sprintf("Duplicate rewrite rule. Already have `%s:%s`, now: `%s`", k, old, s))
		}
		im[k] = v
	}
	files := pk.GoFiles
	if opts.tests {
		files = append(files, pk.TestGoFiles...)
	}
	for _, f := range files {
		full := filepath.Join(pk.Dir, f)
		target := filepath.Join(opts.targetDir, f)
		abs, err := filepath.Abs(target)
		if err != nil {
			abs = target
		}
		fmt.Fprintf(os.Stderr, "`%s`->`%s`\n", full, abs)
		r, err := os.Open(full)
		if err != nil {
			log.Fatalf("Can not be open `%s` for reading. Error: `%s`\n", full, err)
		}
		defer r.Close()
		var w io.Writer
		if !opts.w {
			w = os.Stdout
		} else {
			if opts.targetDir != pk.Dir {
				if err = canWriteSafely(target); err != nil {
					log.Fatalf("Target file `%s` is not empty and not generated by goinline. Error: %s\n", target, err)
				}
			}
		}

		var fset = token.NewFileSet()
		f, err := parser.ParseFile(fset, full, nil, parser.ParseComments)
		if err != nil {
			log.Fatalln(err)
		}
		err = goinline.Inline(fset, f, im)
		if err != nil {
			oops(err.Error())
		}
		// Change target package name if needed.
		if opts.targetPackageName != "" {
			f.Name = &ast.Ident{Name: opts.targetPackageName}
		}
		if w == nil {
			w, err = os.Create(target)
			if err != nil {
				log.Fatalf("Can not be open `%s` for writing. Error: `%s`\n", target, err)
			}
			defer w.(io.Closer).Close()
			if opts.targetDir != pk.Dir {
				_, err = fmt.Fprintf(w, "%s %s\n\n", string(preamble), strings.Join(os.Args[1:], " "))
				if err != nil {
					log.Fatalln(err)
				}
			}
		}
		err = printer.Fprint(w, fset, f)
		if err != nil {
			log.Fatalln(err)
		}
	}
}
Ejemplo n.º 2
0
func (g *generator) processFunc(f *types.Func, iface *Interface) error {
	sig := f.Type().(*types.Signature)
	req := fmt.Sprintf("%s%sRequest", g.typ, f.Name())
	resp := fmt.Sprintf("%s%sResponse", g.typ, f.Name())
	reqS, err := g.writeType(req, sig.Params())
	if err != nil {
		return err
	}
	respS, err := g.writeType(resp, sig.Results())
	if err != nil {
		return err
	}
	iface.M = append(iface.M, method{Name: f.Name(), Req: *reqS, Resp: *respS})
	// Make sure the reciever, the params and return values do not overlap.
	un := uniqueNames{}
	// TODO: add imported packages.
	for _, x := range []string{iface.Receiver, "req", "resp", "raw", "ok", `break`, `default`, `func`, `interface`, `select`, `case`, `defer`, `go`, `map`, `struct`, `chan`, `else`, `goto`, `package`, `switch`, `const`, `fallthrough`, `if`, `range`, `type`, `continue`, `for`, `import`, `return`, `varbool`, `true`, `false`, `uint8`, `uint16`, `uint32`, `uint64`, `int8`, `int16`, `int32`, `int64`, `float32`, `float64`, `complex64`, `complex`, `128`, `string`, `int`, `uint`, `uintptr`, `byte`, `rune`, `iota`, `nil`, `appnd`, `copy`, `delete`, `len`, `cap`, `make`, `new`, `complex`, `real`, `imag`, `close`, `panic`, `recover`, `print`, `println`, `error`} {
		un.get(x)
	}
	for i, a := range reqS.Args2 {
		reqS.Args2[i].Name = un.get(a.Name)
	}
	for i, a := range respS.Args2 {
		respS.Args2[i].Name = un.get(a.Name)
	}

	imports := map[types.Object]*ast.SelectorExpr{}
	for _, p := range toList(sig.Params()) {
		updateDeps(g.rev[p.Type()], g.info, imports)
	}
	for _, p := range toList(sig.Results()) {
		updateDeps(g.rev[p.Type()], g.info, imports)
	}
	imp := cleanImports(imports)
	iface.Imports = append(iface.Imports, imp...)

	im := map[string]goinline.Target{
		"FunT":            goinline.Target{Ident: f.Name(), Imports: nil},
		"RequestT":        goinline.Target{Ident: req, Imports: nil},
		"ResponseT":       goinline.Target{Ident: resp, Imports: nil},
		"makeHTTPBinding": goinline.Target{Ident: fmt.Sprintf("Make%s%sHTTPBinding", g.typ, f.Name()), Imports: nil},
		"NetrpcBinding":   goinline.Target{Ident: fmt.Sprintf("%s%sNetrpcBinding", g.typ, f.Name()), Imports: nil, NoFiltering: true},
		"NewHTTPClient":   goinline.Target{Ident: fmt.Sprintf("New%s%sHTTPClient", g.typ, f.Name()), Imports: nil},
		"NewRPCClient":    goinline.Target{Ident: fmt.Sprintf("New%s%sRPCClient", g.typ, f.Name()), Imports: nil},
	}

	for _, pkg := range g.bindings {
		pk, err := build.Default.Import(pkg, "", 0)
		if err != nil {
			return err
		}

		for _, fn := range pk.GoFiles {
			full := filepath.Join(pk.Dir, fn)

			var fset = token.NewFileSet()
			ff, err := parser.ParseFile(fset, full, nil, parser.ParseComments)
			if err != nil {
				return err
			}

			err = goinline.Inline(fset, ff, im)
			if err != nil {
				return err
			}
			// Change the package name.
			ff.Name = &ast.Ident{Name: g.pkg.Name()}
			target := filepath.Join(g.dir, toSnake(fmt.Sprintf("%s%s_%s", g.typ, f.Name(), fn)))
			w, close, err := g.open(target)
			if err != nil {
				return err
			}
			defer close()
			err = printer.Fprint(w, fset, ff)
			if err != nil {
				return err
			}
		}
	}
	return nil
}