forked from BigfootDev/flatbuffers
[Go] Namespaced imports fix (#5097)
Track and emit required FlatBuffers namespace imports in generated Go code. Update Go code generator by moving most functionality into the generator class, to facilitate namespace tracking. (Note that the git diff in this combined commit may appear large due to this refactoring, but very little code was actually changed.) Update Go code generator by tracking namespace imports when generating FlatBuffers code. Update Go code generator by emitting package imports to correctly reference code in other FlatBuffers namespaces. Create Go test that checks the usage of InParentNamespace objects (as defined in the example schema). Create Docker test that checks the Go language port. Fixes #4883 Fixes #3927 Individual commits: * remove "static" from soon-to-be method functions * move almost all functions into class as methods * set current namespace and emit package names if needed * track imported namespaces * parent namespaces work * docker test for go ^1.11 * update base image name for go docker test * remove cerr debugging * formatting fixes * re-run generate_code.sh * explicitly test namespace imports and usage
This commit is contained in:
1419
src/idl_gen_go.cpp
1419
src/idl_gen_go.cpp
File diff suppressed because it is too large
Load Diff
@@ -26,10 +26,13 @@ go_src=${go_path}/src
|
||||
# Copy flatbuffer Go files to their own package directories to compile the
|
||||
# test binary:
|
||||
mkdir -p ${go_src}/MyGame/Example
|
||||
mkdir -p ${go_src}/MyGame/Example2
|
||||
mkdir -p ${go_src}/github.com/google/flatbuffers/go
|
||||
mkdir -p ${go_src}/flatbuffers_test
|
||||
|
||||
cp -a MyGame/*.go ./go_gen/src/MyGame/
|
||||
cp -a MyGame/Example/*.go ./go_gen/src/MyGame/Example/
|
||||
cp -a MyGame/Example2/*.go ./go_gen/src/MyGame/Example2/
|
||||
# do not compile the gRPC generated files, which are not tested by go_test.go
|
||||
# below, but have their own test.
|
||||
rm ./go_gen/src/MyGame/Example/*_grpc.go
|
||||
|
||||
@@ -4,6 +4,8 @@ package Example
|
||||
|
||||
import (
|
||||
flatbuffers "github.com/google/flatbuffers/go"
|
||||
|
||||
MyGame "MyGame"
|
||||
)
|
||||
|
||||
/// an example documentation comment: monster object
|
||||
@@ -516,12 +518,12 @@ func (rcv *Monster) VectorOfDoublesLength() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *Monster) ParentNamespaceTest(obj *InParentNamespace) *InParentNamespace {
|
||||
func (rcv *Monster) ParentNamespaceTest(obj *MyGame.InParentNamespace) *MyGame.InParentNamespace {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(72))
|
||||
if o != 0 {
|
||||
x := rcv._tab.Indirect(o + rcv._tab.Pos)
|
||||
if obj == nil {
|
||||
obj = new(InParentNamespace)
|
||||
obj = new(MyGame.InParentNamespace)
|
||||
}
|
||||
obj.Init(rcv._tab.Bytes, x)
|
||||
return obj
|
||||
|
||||
7
tests/docker/languages/Dockerfile.testing.golang.1_11
Normal file
7
tests/docker/languages/Dockerfile.testing.golang.1_11
Normal file
@@ -0,0 +1,7 @@
|
||||
FROM golang:1.11-stretch as base
|
||||
WORKDIR /code
|
||||
ADD . .
|
||||
RUN cp flatc_debian_stretch flatc
|
||||
WORKDIR /code/tests
|
||||
RUN go version
|
||||
RUN ./GoTest.sh
|
||||
@@ -17,7 +17,9 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
mygame "MyGame" // refers to generated code
|
||||
example "MyGame/Example" // refers to generated code
|
||||
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
@@ -111,6 +113,9 @@ func TestAll(t *testing.T) {
|
||||
// Check Builder.CreateByteVector
|
||||
CheckCreateByteVector(t.Fatalf)
|
||||
|
||||
// Check a parent namespace import
|
||||
CheckParentNamespace(t.Fatalf)
|
||||
|
||||
// If the filename of the FlatBuffers file generated by the Java test
|
||||
// is given, check that Go code can read it, and that Go code
|
||||
// generates an identical buffer when used to create the example data:
|
||||
@@ -1444,6 +1449,54 @@ func CheckCreateByteVector(fail func(string, ...interface{})) {
|
||||
}
|
||||
}
|
||||
|
||||
func CheckParentNamespace(fail func(string, ...interface{})) {
|
||||
var empty, nonempty []byte
|
||||
|
||||
// create monster with an empty parent namespace field
|
||||
{
|
||||
builder := flatbuffers.NewBuilder(0)
|
||||
|
||||
example.MonsterStart(builder)
|
||||
m := example.MonsterEnd(builder)
|
||||
builder.Finish(m)
|
||||
|
||||
empty = make([]byte, len(builder.FinishedBytes()))
|
||||
copy(empty, builder.FinishedBytes())
|
||||
}
|
||||
|
||||
// create monster with a non-empty parent namespace field
|
||||
{
|
||||
builder := flatbuffers.NewBuilder(0)
|
||||
mygame.InParentNamespaceStart(builder)
|
||||
pn := mygame.InParentNamespaceEnd(builder)
|
||||
|
||||
example.MonsterStart(builder)
|
||||
example.MonsterAddParentNamespaceTest(builder, pn)
|
||||
m := example.MonsterEnd(builder)
|
||||
|
||||
builder.Finish(m)
|
||||
|
||||
nonempty = make([]byte, len(builder.FinishedBytes()))
|
||||
copy(nonempty, builder.FinishedBytes())
|
||||
}
|
||||
|
||||
// read monster with empty parent namespace field
|
||||
{
|
||||
m := example.GetRootAsMonster(empty, 0)
|
||||
if m.ParentNamespaceTest(nil) != nil {
|
||||
fail("expected nil ParentNamespaceTest for empty field")
|
||||
}
|
||||
}
|
||||
|
||||
// read monster with non-empty parent namespace field
|
||||
{
|
||||
m := example.GetRootAsMonster(nonempty, 0)
|
||||
if m.ParentNamespaceTest(nil) == nil {
|
||||
fail("expected non-nil ParentNamespaceTest for non-empty field")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Include simple random number generator to ensure results will be the
|
||||
// same cross platform.
|
||||
// http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator
|
||||
|
||||
@@ -4,6 +4,8 @@ package NamespaceA
|
||||
|
||||
import (
|
||||
flatbuffers "github.com/google/flatbuffers/go"
|
||||
|
||||
NamespaceC "NamespaceC"
|
||||
)
|
||||
|
||||
type SecondTableInA struct {
|
||||
@@ -26,12 +28,12 @@ func (rcv *SecondTableInA) Table() flatbuffers.Table {
|
||||
return rcv._tab
|
||||
}
|
||||
|
||||
func (rcv *SecondTableInA) ReferToC(obj *TableInC) *TableInC {
|
||||
func (rcv *SecondTableInA) ReferToC(obj *NamespaceC.TableInC) *NamespaceC.TableInC {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||
if o != 0 {
|
||||
x := rcv._tab.Indirect(o + rcv._tab.Pos)
|
||||
if obj == nil {
|
||||
obj = new(TableInC)
|
||||
obj = new(NamespaceC.TableInC)
|
||||
}
|
||||
obj.Init(rcv._tab.Bytes, x)
|
||||
return obj
|
||||
|
||||
@@ -4,6 +4,8 @@ package NamespaceA
|
||||
|
||||
import (
|
||||
flatbuffers "github.com/google/flatbuffers/go"
|
||||
|
||||
NamespaceA__NamespaceB "NamespaceA/NamespaceB"
|
||||
)
|
||||
|
||||
type TableInFirstNS struct {
|
||||
@@ -26,12 +28,12 @@ func (rcv *TableInFirstNS) Table() flatbuffers.Table {
|
||||
return rcv._tab
|
||||
}
|
||||
|
||||
func (rcv *TableInFirstNS) FooTable(obj *TableInNestedNS) *TableInNestedNS {
|
||||
func (rcv *TableInFirstNS) FooTable(obj *NamespaceA__NamespaceB.TableInNestedNS) *NamespaceA__NamespaceB.TableInNestedNS {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||
if o != 0 {
|
||||
x := rcv._tab.Indirect(o + rcv._tab.Pos)
|
||||
if obj == nil {
|
||||
obj = new(TableInNestedNS)
|
||||
obj = new(NamespaceA__NamespaceB.TableInNestedNS)
|
||||
}
|
||||
obj.Init(rcv._tab.Bytes, x)
|
||||
return obj
|
||||
@@ -51,12 +53,12 @@ func (rcv *TableInFirstNS) MutateFooEnum(n EnumInNestedNS) bool {
|
||||
return rcv._tab.MutateInt8Slot(6, n)
|
||||
}
|
||||
|
||||
func (rcv *TableInFirstNS) FooStruct(obj *StructInNestedNS) *StructInNestedNS {
|
||||
func (rcv *TableInFirstNS) FooStruct(obj *NamespaceA__NamespaceB.StructInNestedNS) *NamespaceA__NamespaceB.StructInNestedNS {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
|
||||
if o != 0 {
|
||||
x := o + rcv._tab.Pos
|
||||
if obj == nil {
|
||||
obj = new(StructInNestedNS)
|
||||
obj = new(NamespaceA__NamespaceB.StructInNestedNS)
|
||||
}
|
||||
obj.Init(rcv._tab.Bytes, x)
|
||||
return obj
|
||||
|
||||
@@ -4,6 +4,8 @@ package NamespaceC
|
||||
|
||||
import (
|
||||
flatbuffers "github.com/google/flatbuffers/go"
|
||||
|
||||
NamespaceA "NamespaceA"
|
||||
)
|
||||
|
||||
type TableInC struct {
|
||||
@@ -26,12 +28,12 @@ func (rcv *TableInC) Table() flatbuffers.Table {
|
||||
return rcv._tab
|
||||
}
|
||||
|
||||
func (rcv *TableInC) ReferToA1(obj *TableInFirstNS) *TableInFirstNS {
|
||||
func (rcv *TableInC) ReferToA1(obj *NamespaceA.TableInFirstNS) *NamespaceA.TableInFirstNS {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||
if o != 0 {
|
||||
x := rcv._tab.Indirect(o + rcv._tab.Pos)
|
||||
if obj == nil {
|
||||
obj = new(TableInFirstNS)
|
||||
obj = new(NamespaceA.TableInFirstNS)
|
||||
}
|
||||
obj.Init(rcv._tab.Bytes, x)
|
||||
return obj
|
||||
@@ -39,12 +41,12 @@ func (rcv *TableInC) ReferToA1(obj *TableInFirstNS) *TableInFirstNS {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rcv *TableInC) ReferToA2(obj *SecondTableInA) *SecondTableInA {
|
||||
func (rcv *TableInC) ReferToA2(obj *NamespaceA.SecondTableInA) *NamespaceA.SecondTableInA {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
|
||||
if o != 0 {
|
||||
x := rcv._tab.Indirect(o + rcv._tab.Pos)
|
||||
if obj == nil {
|
||||
obj = new(SecondTableInA)
|
||||
obj = new(NamespaceA.SecondTableInA)
|
||||
}
|
||||
obj.Init(rcv._tab.Bytes, x)
|
||||
return obj
|
||||
|
||||
Reference in New Issue
Block a user