bind: format generated go code before comparing with golden files

bind_test.go compares the generated Go files against golden files
checked in the repository. The bind package formats some of the
generated Go files, so any changes in the go formatter can break
the tests.

This change makes the test more robust by applying formatting based
on the currently used go version. Since a golden file often
includes multiple go files generated by the bind, the `gofmt`
function splits the golden file using the gobindPreamble marker
and then run format.Source for each chunk. In order to ease the
golden file splitting, this CL also moves the gobindPreamble
to the beginning of each generated file consistently.

It turned out bind omits formatting for some go files (generated
for reverse binding). That needs to be fixed but it is a much
bigger fix. Thus, in this CL, we apply the formatting on the
bind's output as well.

This CL also updates the gobindPreamble to follow the style guide
for generated code. https://golang.org/s/generatedcode

Fixes golang/go#34619

Change-Id: Ia2957693154face2848e051ebbb2373e95d79593
Reviewed-on: https://go-review.googlesource.com/c/mobile/+/198322
Run-TryBot: Hyang-Ah Hana Kim <hyangah@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
This commit is contained in:
Hana Kim
2019-10-02 17:59:09 +00:00
committed by Hyang-Ah Hana Kim
parent d3ece3b6da
commit 6d0d39b2ca
73 changed files with 653 additions and 431 deletions
+2
View File
@@ -20,6 +20,8 @@ import (
"io"
)
const gobindPreamble = "// Code generated by gobind. DO NOT EDIT.\n\n"
type (
GeneratorConfig struct {
Writer io.Writer
+37 -2
View File
@@ -5,6 +5,7 @@ import (
"flag"
"go/ast"
"go/build"
"go/format"
"go/importer"
"go/parser"
"go/token"
@@ -484,14 +485,26 @@ func testGenGo(t *testing.T, filename string, buf *bytes.Buffer, pkg *types.Pack
t.Errorf("%s: %v", filename, err)
return
}
out := writeTempFile(t, "go", buf.Bytes())
// TODO(hyangah): let GenGo format the generated go files.
out := writeTempFile(t, "go", gofmt(t, buf.Bytes()))
defer os.Remove(out)
golden := filename
if golden == "" {
golden = "testdata/universe"
}
golden += ".golden"
if diffstr := diff(golden, out); diffstr != "" {
goldenContents, err := ioutil.ReadFile(golden)
if err != nil {
t.Fatalf("failed to read golden file: %v", err)
}
// format golden file using the current go version's formatting rule.
formattedGolden := writeTempFile(t, "go", gofmt(t, goldenContents))
defer os.Remove(formattedGolden)
if diffstr := diff(formattedGolden, out); diffstr != "" {
t.Errorf("%s: does not match Go golden:\n%s", filename, diffstr)
if *updateFlag {
@@ -503,6 +516,28 @@ func testGenGo(t *testing.T, filename string, buf *bytes.Buffer, pkg *types.Pack
}
}
// gofmt formats the collection of Go source files auto-generated by gobind.
func gofmt(t *testing.T, src []byte) []byte {
t.Helper()
buf := &bytes.Buffer{}
mark := []byte(gobindPreamble)
for i, c := range bytes.Split(src, mark) {
if i == 0 {
buf.Write(c)
continue
}
tmp := append(mark, c...)
out, err := format.Source(tmp)
if err != nil {
t.Fatalf("failed to format Go file: error=%v\n----\n%s\n----", err, tmp)
}
if _, err := buf.Write(out); err != nil {
t.Fatalf("failed to write formatted file to buffer: %v", err)
}
}
return buf.Bytes()
}
func TestCustomPrefix(t *testing.T) {
const datafile = "testdata/customprefix.go"
pkg, file := typeCheck(t, datafile, "")
+11 -13
View File
@@ -164,7 +164,7 @@ func (g *ClassGen) Packages() []string {
func (g *ClassGen) GenPackage(idx int) {
jpkg := g.jpkgs[idx]
g.Printf("// File is generated by gobind. Do not edit.\n\n")
g.Printf(gobindPreamble)
g.Printf("package %s\n\n", path.Base(jpkg))
g.Printf("import \"Java\"\n\n")
g.Printf("const _ = Java.Dummy\n\n")
@@ -573,7 +573,11 @@ func (g *ClassGen) genGo(cls *java.Class) {
g.Outdent()
g.Printf("}\n\n")
g.Printf("type proxy_class_%s _seq.Ref\n\n", cls.JNIName)
g.Printf("func (p *proxy_class_%s) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }\n\n", cls.JNIName)
g.Printf("func (p *proxy_class_%s) Bind_proxy_refnum__() int32 {\n", cls.JNIName)
g.Indent()
g.Printf("return (*_seq.Ref)(p).Bind_IncNum()\n")
g.Outdent()
g.Printf("}\n\n")
for _, fs := range cls.AllMethods {
if !g.isFuncSetSupported(fs) {
continue
@@ -901,23 +905,20 @@ func flattenName(n string) string {
}
var (
classesPkgHeader = `// File is generated by gobind. Do not edit.
classesPkgHeader = gobindPreamble + `
package Java
// Used to silence this package not used errors
const Dummy = 0
`
classesCHeader = `// File is generated by gobind. Do not edit.
classesCHeader = gobindPreamble + `
#include <jni.h>
#include "seq.h"
#include "classes.h"
`
classesHHeader = `// File is generated by gobind. Do not edit.
classesHHeader = gobindPreamble + `
#include <jni.h>
#include "seq.h"
@@ -925,12 +926,9 @@ extern void init_proxies();
`
javaImplHeader = `// File is generated by gobind. Do not edit.
`
classesGoHeader = `// File is generated by gobind. Do not edit.
javaImplHeader = gobindPreamble
classesGoHeader = gobindPreamble + `
package main
/*
+7 -4
View File
@@ -32,10 +32,9 @@ type goGen struct {
}
const (
goPreamble = `// Package main is an autogenerated binder stub for package %[1]s.
// gobind -lang=go %[2]s
goPreamble = gobindPreamble + `// Package main is an autogenerated binder stub for package %[1]s.
//
// File is generated by gobind. Do not edit.
// autogenerated by gobind -lang=go %[2]s
package main
/*
@@ -311,7 +310,11 @@ func (g *goGen) genInterface(obj *types.TypeName) {
}
g.Printf("type proxy%s_%s _seq.Ref\n\n", g.pkgPrefix, obj.Name())
g.Printf("func (p *proxy%s_%s) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }\n\n", g.pkgPrefix, obj.Name())
g.Printf("func (p *proxy%s_%s) Bind_proxy_refnum__() int32 {\n", g.pkgPrefix, obj.Name())
g.Indent()
g.Printf("return (*_seq.Ref)(p).Bind_IncNum()\n")
g.Outdent()
g.Printf("}\n\n")
for _, m := range summary.callable {
if !g.isSigSupported(m.Type()) {
+6 -9
View File
@@ -1701,19 +1701,17 @@ func isJavaType(t types.Type) bool {
}
const (
javaPreamble = `// Java class %[1]s.%[2]s is a proxy for talking to a Go program.
// gobind %[3]s %[4]s
javaPreamble = gobindPreamble + `// Java class %[1]s.%[2]s is a proxy for talking to a Go program.
//
// File is generated by gobind. Do not edit.
// autogenerated by gobind %[3]s %[4]s
package %[1]s;
import go.Seq;
`
cPreamble = `// JNI functions for the Go <=> Java bridge.
// gobind %[1]s %[2]s
cPreamble = gobindPreamble + `// JNI functions for the Go <=> Java bridge.
//
// File is generated by gobind. Do not edit.
// autogenerated by gobind %[1]s %[2]s
#include <android/log.h>
#include <stdint.h>
@@ -1721,10 +1719,9 @@ import go.Seq;
#include "_cgo_export.h"
`
hPreamble = `// JNI function headers for the Go <=> Java bridge.
// gobind %[1]s %[2]s
hPreamble = gobindPreamble + `// JNI function headers for the Go <=> Java bridge.
//
// File is generated by gobind. Do not edit.
// autogenerated by gobind %[1]s %[2]s
#ifndef __%[3]s_H__
#define __%[3]s_H__
+5 -5
View File
@@ -62,7 +62,7 @@ func (g *ObjcWrapper) Init(types []*objc.Named, genNames []string) {
}
func (g *ObjcWrapper) GenM() {
g.Printf("//File is generated by gobind. Do not edit.\n\n")
g.Printf(gobindPreamble)
// For objc_msgSend* functions.
g.Printf("@import ObjectiveC.message;\n")
g.Printf("#include \"seq.h\"\n")
@@ -219,7 +219,7 @@ func (g *ObjcWrapper) genM(n *objc.Named) {
}
func (g *ObjcWrapper) GenH() {
g.Printf("//File is generated by gobind. Do not edit.\n\n")
g.Printf(gobindPreamble)
g.Printf("#include \"seq.h\"\n\n")
for _, m := range g.modules {
g.Printf("@import %s;\n", m)
@@ -314,7 +314,7 @@ func (g *ObjcWrapper) genCFuncDecl(prefix, name string, f *objc.Func) {
}
func (g *ObjcWrapper) GenGo() {
g.Printf("// File is generated by gobind. Do not edit.\n\n")
g.Printf(gobindPreamble)
g.Printf("package main\n\n")
g.Printf("// #include \"interfaces.h\"\n")
g.Printf("import \"C\"\n\n")
@@ -533,7 +533,7 @@ func (g *ObjcWrapper) Packages() []string {
func (g *ObjcWrapper) GenPackage(idx int) {
pkg := g.pkgNames[idx]
g.Printf("//File is generated by gobind. Do not edit.\n\n")
g.Printf(gobindPreamble)
g.Printf("package %s\n\n", path.Base(pkg))
g.Printf("import \"ObjC\"\n\n")
g.Printf("const _ = ObjC.Dummy\n\n")
@@ -558,7 +558,7 @@ func (g *ObjcWrapper) GenPackage(idx int) {
}
func (g *ObjcWrapper) GenInterfaces() {
g.Printf("//File is generated by gobind. Do not edit.\n\n")
g.Printf(gobindPreamble)
g.Printf("package ObjC\n\n")
g.Printf("// Used to silence this package not used errors\n")
g.Printf("const Dummy = 0\n\n")
+3 -2
View File
@@ -1,7 +1,8 @@
// Code generated by gobind. DO NOT EDIT.
// Package main is an autogenerated binder stub for package basictypes.
// gobind -lang=go basictypes
//
// File is generated by gobind. Do not edit.
// autogenerated by gobind -lang=go basictypes
package main
/*
+3 -2
View File
@@ -1,7 +1,8 @@
// Code generated by gobind. DO NOT EDIT.
// JNI functions for the Go <=> Java bridge.
// gobind -lang=java basictypes
//
// File is generated by gobind. Do not edit.
// autogenerated by gobind -lang=java basictypes
#include <android/log.h>
#include <stdint.h>
+3 -2
View File
@@ -1,7 +1,8 @@
// Code generated by gobind. DO NOT EDIT.
// Java class basictypes.Basictypes is a proxy for talking to a Go program.
// gobind -lang=java basictypes
//
// File is generated by gobind. Do not edit.
// autogenerated by gobind -lang=java basictypes
package basictypes;
import go.Seq;
+3 -2
View File
@@ -1,7 +1,8 @@
// Code generated by gobind. DO NOT EDIT.
// JNI function headers for the Go <=> Java bridge.
// gobind -lang=java basictypes
//
// File is generated by gobind. Do not edit.
// autogenerated by gobind -lang=java basictypes
#ifndef __Basictypes_H__
#define __Basictypes_H__
+179 -141
View File
File diff suppressed because it is too large Load Diff
+5 -3
View File
@@ -1,4 +1,5 @@
// File is generated by gobind. Do not edit.
// Code generated by gobind. DO NOT EDIT.
#include <jni.h>
#include "seq.h"
@@ -727,10 +728,11 @@ ret_nstring cproxy_java_io_Console_toString(jint this) {
return __res;
}
// Code generated by gobind. DO NOT EDIT.
// JNI functions for the Go <=> Java bridge.
// gobind -lang=java classes
//
// File is generated by gobind. Do not edit.
// autogenerated by gobind -lang=java classes
#include <android/log.h>
#include <stdint.h>
+15 -10
View File
@@ -1,7 +1,8 @@
// Code generated by gobind. DO NOT EDIT.
// Java class java.Future is a proxy for talking to a Go program.
// gobind -lang=java classes
//
// File is generated by gobind. Do not edit.
// autogenerated by gobind -lang=java classes
package java;
import go.Seq;
@@ -32,10 +33,11 @@ public final class Future implements Seq.GoObject, java.util.concurrent.Future {
@Override public native java.lang.Object get(long p0, java.util.concurrent.TimeUnit p1) throws java.lang.InterruptedException, java.util.concurrent.ExecutionException, java.util.concurrent.TimeoutException;
}
// Code generated by gobind. DO NOT EDIT.
// Java class java.InputStream is a proxy for talking to a Go program.
// gobind -lang=java classes
//
// File is generated by gobind. Do not edit.
// autogenerated by gobind -lang=java classes
package java;
import go.Seq;
@@ -64,10 +66,11 @@ public final class InputStream extends java.io.InputStream implements Seq.GoObje
@Override public native int read() throws java.io.IOException;
}
// Code generated by gobind. DO NOT EDIT.
// Java class java.Object is a proxy for talking to a Go program.
// gobind -lang=java classes
//
// File is generated by gobind. Do not edit.
// autogenerated by gobind -lang=java classes
package java;
import go.Seq;
@@ -93,10 +96,11 @@ public final class Object extends java.lang.Object implements Seq.GoObject {
}
// Code generated by gobind. DO NOT EDIT.
// Java class java.Runnable is a proxy for talking to a Go program.
// gobind -lang=java classes
//
// File is generated by gobind. Do not edit.
// autogenerated by gobind -lang=java classes
package java;
import go.Seq;
@@ -123,10 +127,11 @@ public final class Runnable implements Seq.GoObject, java.lang.Runnable {
@Override public native void run();
}
// Code generated by gobind. DO NOT EDIT.
// Java class java.Java is a proxy for talking to a Go program.
// gobind -lang=java classes
//
// File is generated by gobind. Do not edit.
// autogenerated by gobind -lang=java classes
package java;
import go.Seq;
+5 -3
View File
@@ -1,4 +1,5 @@
// File is generated by gobind. Do not edit.
// Code generated by gobind. DO NOT EDIT.
#include <jni.h>
#include "seq.h"
@@ -80,10 +81,11 @@ extern ret_jint cproxy_s_java_util_Spliterators_iterator__Ljava_util_Spliterator
extern ret_jint cproxy_s_java_util_Spliterators_iterator__Ljava_util_Spliterator_00024OfLong_2(jint a0);
extern ret_jint cproxy_s_java_util_Spliterators_iterator__Ljava_util_Spliterator_00024OfDouble_2(jint a0);
extern ret_jint cproxy_s_java_lang_System_console();
// Code generated by gobind. DO NOT EDIT.
// JNI function headers for the Go <=> Java bridge.
// gobind -lang=java classes
//
// File is generated by gobind. Do not edit.
// autogenerated by gobind -lang=java classes
#ifndef __Java_H__
#define __Java_H__
+3 -2
View File
@@ -1,7 +1,8 @@
// Code generated by gobind. DO NOT EDIT.
// JNI functions for the Go <=> Java bridge.
// gobind -lang=java -javapkg=com.example customprefix
//
// File is generated by gobind. Do not edit.
// autogenerated by gobind -lang=java -javapkg=com.example customprefix
#include <android/log.h>
#include <stdint.h>
+3 -2
View File
@@ -1,7 +1,8 @@
// Code generated by gobind. DO NOT EDIT.
// Java class com.example.customprefix.Customprefix is a proxy for talking to a Go program.
// gobind -lang=java -javapkg=com.example customprefix
//
// File is generated by gobind. Do not edit.
// autogenerated by gobind -lang=java -javapkg=com.example customprefix
package com.example.customprefix;
import go.Seq;
+3 -2
View File
@@ -1,7 +1,8 @@
// Code generated by gobind. DO NOT EDIT.
// JNI function headers for the Go <=> Java bridge.
// gobind -lang=java -javapkg=com.example customprefix
//
// File is generated by gobind. Do not edit.
// autogenerated by gobind -lang=java -javapkg=com.example customprefix
#ifndef __Customprefix_H__
#define __Customprefix_H__
+6 -3
View File
@@ -1,7 +1,8 @@
// Code generated by gobind. DO NOT EDIT.
// Package main is an autogenerated binder stub for package doc.
// gobind -lang=go doc
//
// File is generated by gobind. Do not edit.
// autogenerated by gobind -lang=go doc
package main
/*
@@ -126,7 +127,9 @@ func proxydoc_I_IM(refnum C.int32_t) {
type proxydoc_I _seq.Ref
func (p *proxydoc_I) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }
func (p *proxydoc_I) Bind_proxy_refnum__() int32 {
return (*_seq.Ref)(p).Bind_IncNum()
}
func (p *proxydoc_I) IM() {
C.cproxydoc_I_IM(C.int32_t(p.Bind_proxy_refnum__()))
+3 -2
View File
@@ -1,7 +1,8 @@
// Code generated by gobind. DO NOT EDIT.
// JNI functions for the Go <=> Java bridge.
// gobind -lang=java doc
//
// File is generated by gobind. Do not edit.
// autogenerated by gobind -lang=java doc
#include <android/log.h>
#include <stdint.h>
+15 -10
View File
@@ -1,7 +1,8 @@
// Code generated by gobind. DO NOT EDIT.
// Java class doc.NoDoc is a proxy for talking to a Go program.
// gobind -lang=java doc
//
// File is generated by gobind. Do not edit.
// autogenerated by gobind -lang=java doc
package doc;
import go.Seq;
@@ -44,10 +45,11 @@ public final class NoDoc implements Seq.Proxy {
}
}
// Code generated by gobind. DO NOT EDIT.
// Java class doc.S is a proxy for talking to a Go program.
// gobind -lang=java doc
//
// File is generated by gobind. Do not edit.
// autogenerated by gobind -lang=java doc
package doc;
import go.Seq;
@@ -177,10 +179,11 @@ public final class S implements Seq.Proxy {
}
}
// Code generated by gobind. DO NOT EDIT.
// Java class doc.S2 is a proxy for talking to a Go program.
// gobind -lang=java doc
//
// File is generated by gobind. Do not edit.
// autogenerated by gobind -lang=java doc
package doc;
import go.Seq;
@@ -223,10 +226,11 @@ public final class S2 implements Seq.Proxy {
}
}
// Code generated by gobind. DO NOT EDIT.
// Java class doc.I is a proxy for talking to a Go program.
// gobind -lang=java doc
//
// File is generated by gobind. Do not edit.
// autogenerated by gobind -lang=java doc
package doc;
import go.Seq;
@@ -242,10 +246,11 @@ public interface I {
}
// Code generated by gobind. DO NOT EDIT.
// Java class doc.Doc is a proxy for talking to a Go program.
// gobind -lang=java doc
//
// File is generated by gobind. Do not edit.
// autogenerated by gobind -lang=java doc
package doc;
import go.Seq;

Some files were not shown because too many files have changed in this diff Show More