func TestGenGoJavaWrappers(t *testing.T) { if !java.IsAvailable() { t.Skipf("java is not available") } for _, filename := range javaTests { var buf bytes.Buffer refs := fileRefs(t, filename, "Java/") classes, err := java.Import("", "", refs) if err != nil { t.Fatal(err) } tmpGopath, err := ioutil.TempDir(os.TempDir(), "gomobile-bind-test-") if err != nil { t.Fatal(err) } defer os.RemoveAll(tmpGopath) cg := genJavaPackages(t, tmpGopath, classes, &buf) pkg := typeCheck(t, filename, tmpGopath) cg.GenGo() testGenGo(t, filename, &buf, pkg) } }
func main() { flag.Parse() if *lang != "java" && *javaPkg != "" { log.Fatalf("Invalid option -javapkg for gobind -lang=%s", *lang) } else if *lang != "objc" && *prefix != "" { log.Fatalf("Invalid option -prefix for gobind -lang=%s", *lang) } oldCtx := build.Default ctx := &build.Default var allPkg []*build.Package for _, path := range flag.Args() { pkg, err := ctx.Import(path, ".", build.ImportComment) if err != nil { log.Fatalf("package %q: %v", path, err) } allPkg = append(allPkg, pkg) } var classes []*java.Class refs, err := importers.AnalyzePackages(allPkg, "Java/") if err != nil { log.Fatal(err) } if len(refs.Refs) > 0 { classes, err = java.Import(*bootclasspath, *classpath, refs) if err != nil { log.Fatal(err) } if len(classes) > 0 { tmpGopath, err := ioutil.TempDir(os.TempDir(), "gobind-") if err != nil { log.Fatal(err) } defer os.RemoveAll(tmpGopath) if err := genJavaPackages(ctx, tmpGopath, classes); err != nil { log.Fatal(err) } gopath := ctx.GOPATH if gopath != "" { gopath = string(filepath.ListSeparator) } ctx.GOPATH = gopath + tmpGopath } } typePkgs := make([]*types.Package, len(allPkg)) fset := token.NewFileSet() conf := &types.Config{ Importer: importer.Default(), } conf.Error = func(err error) { // Ignore errors. They're probably caused by as-yet undefined // Java wrappers. } for i, pkg := range allPkg { var files []*ast.File for _, name := range pkg.GoFiles { f, err := parser.ParseFile(fset, filepath.Join(pkg.Dir, name), nil, 0) if err != nil { log.Fatalf("Failed to parse Go file %s: %v", name, err) } files = append(files, f) } tpkg, _ := conf.Check(pkg.Name, fset, files, nil) typePkgs[i] = tpkg } build.Default = oldCtx for _, pkg := range typePkgs { genPkg(pkg, typePkgs, classes) } // Generate the error package and support files genPkg(nil, typePkgs, classes) os.Exit(exitStatus) }
func TestGenJava(t *testing.T) { allTests := tests if java.IsAvailable() { allTests = append(append([]string{}, allTests...), javaTests...) } for _, filename := range allTests { refs := fileRefs(t, filename, "Java/") classes, err := java.Import("", "", refs) if err != nil { t.Fatal(err) } var cg *ClassGen tmpGopath := "" var buf bytes.Buffer if len(classes) > 0 { tmpGopath, err = ioutil.TempDir(os.TempDir(), "gomobile-bind-test-") if err != nil { t.Fatal(err) } defer os.RemoveAll(tmpGopath) cg = genJavaPackages(t, tmpGopath, classes, new(bytes.Buffer)) cg.Buf = &buf } pkg := typeCheck(t, filename, tmpGopath) g := &JavaGen{ Generator: &Generator{ Printer: &Printer{Buf: &buf, IndentEach: []byte(" ")}, Fset: fset, AllPkg: []*types.Package{pkg}, Pkg: pkg, }, } g.Init(classes) testCases := []struct { suffix string gen func() error }{ { ".java.golden", func() error { for i := range g.ClassNames() { if err := g.GenClass(i); err != nil { return err } } return g.GenJava() }, }, { ".java.c.golden", func() error { if cg != nil { cg.GenC() } return g.GenC() }, }, { ".java.h.golden", func() error { if cg != nil { cg.GenH() } return g.GenH() }, }, } for _, tc := range testCases { buf.Reset() if err := tc.gen(); err != nil { t.Errorf("%s: %v", filename, err) continue } out := writeTempFile(t, "generated"+tc.suffix, buf.Bytes()) defer os.Remove(out) golden := filename[:len(filename)-len(".go")] + tc.suffix if diffstr := diff(golden, out); diffstr != "" { t.Errorf("%s: does not match Java golden:\n%s", filename, diffstr) if *updateFlag { t.Logf("Updating %s...", golden) if err := exec.Command("/bin/cp", out, golden).Run(); err != nil { t.Errorf("Update failed: %s", err) } } } } } }
func GenClasses(pkgs []*build.Package, srcDir, jpkgSrc string) ([]*java.Class, error) { refs, err := importers.AnalyzePackages(pkgs, "Java/") if err != nil { return nil, err } bClspath, err := bootClasspath() if err != nil { return nil, err } classes, err := java.Import(bClspath, bindClasspath, refs) if err != nil { return nil, err } var buf bytes.Buffer g := &bind.ClassGen{ Printer: &bind.Printer{ IndentEach: []byte("\t"), Buf: &buf, }, } g.Init(classes) for i, jpkg := range g.Packages() { pkgDir := filepath.Join(jpkgSrc, "src", "Java", jpkg) if err := os.MkdirAll(pkgDir, 0700); err != nil { return nil, err } pkgFile := filepath.Join(pkgDir, "package.go") generate := func(w io.Writer) error { if buildN { return nil } buf.Reset() g.GenPackage(i) _, err := io.Copy(w, &buf) return err } if err := writeFile(pkgFile, generate); err != nil { return nil, fmt.Errorf("failed to create the Java wrapper package %s: %v", jpkg, err) } } generate := func(w io.Writer) error { if buildN { return nil } buf.Reset() g.GenGo() _, err := io.Copy(w, &buf) return err } if err := writeFile(filepath.Join(srcDir, "classes.go"), generate); err != nil { return nil, fmt.Errorf("failed to create the Java classes Go file: %v", err) } generate = func(w io.Writer) error { if buildN { return nil } buf.Reset() g.GenH() _, err := io.Copy(w, &buf) return err } if err := writeFile(filepath.Join(srcDir, "classes.h"), generate); err != nil { return nil, fmt.Errorf("failed to create the Java classes header file: %v", err) } generate = func(w io.Writer) error { if buildN { return nil } buf.Reset() g.GenC() _, err := io.Copy(w, &buf) return err } if err := writeFile(filepath.Join(srcDir, "classes.c"), generate); err != nil { return nil, fmt.Errorf("failed to create the Java classes C file: %v", err) } generate = func(w io.Writer) error { if buildN { return nil } buf.Reset() g.GenInterfaces() _, err := io.Copy(w, &buf) return err } if err := writeFile(filepath.Join(jpkgSrc, "src", "Java", "interfaces.go"), generate); err != nil { return nil, fmt.Errorf("failed to create the Java classes interfaces file: %v", err) } return classes, nil }