This is an automated email from the ASF dual-hosted git repository.
altay pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/beam.git
The following commit(s) were added to refs/heads/master by this push:
new 83fe192 [BEAM-6825] Improve Combine error messages. (#8243)
83fe192 is described below
commit 83fe192b9f58a0c99d5718a5dea087d438fa5d7c
Author: Robert Burke <[email protected]>
AuthorDate: Tue Apr 9 09:40:48 2019 -0700
[BEAM-6825] Improve Combine error messages. (#8243)
* [BEAM-6825] Improve Combine error messages.
* !fixup Address style nits, and error readability.
---
sdks/go/pkg/beam/core/funcx/signature.go | 46 +++-
sdks/go/pkg/beam/core/funcx/signature_test.go | 16 +-
sdks/go/pkg/beam/core/graph/fn.go | 135 +++++++++-
sdks/go/pkg/beam/core/graph/fn_test.go | 311 +++++++++++++++++++++++
sdks/go/pkg/beam/transforms/stats/mean.go | 9 +-
sdks/go/pkg/beam/transforms/stats/stats.shims.go | 189 +++++++-------
6 files changed, 582 insertions(+), 124 deletions(-)
diff --git a/sdks/go/pkg/beam/core/funcx/signature.go
b/sdks/go/pkg/beam/core/funcx/signature.go
index fbb0ad6..6caa5cd 100644
--- a/sdks/go/pkg/beam/core/funcx/signature.go
+++ b/sdks/go/pkg/beam/core/funcx/signature.go
@@ -108,23 +108,32 @@ func replace(list []reflect.Type, old, new reflect.Type)
[]reflect.Type {
// "foo" would satisfy (context.Context, string) -> bool and only "bar" would
// satisfy (int) -> bool.
func Satisfy(fn interface{}, sig *Signature) error {
- value := reflect.ValueOf(fn)
- if value.Kind() != reflect.Func {
- return fmt.Errorf("not a function: %v", value)
- }
-
var in, out []reflect.Type
- for i := 0; i < value.Type().NumIn(); i++ {
- in = append(in, value.Type().In(i))
+ var typ reflect.Type
+ switch fx := fn.(type) {
+ case *Fn:
+ typ = fx.Fn.Type()
+ case reflectx.Func:
+ typ = fx.Type()
+ default:
+ value := reflect.ValueOf(fn)
+ if value.Kind() != reflect.Func {
+ return fmt.Errorf("not a function: %v", value)
+ }
+ typ = value.Type()
+ }
+ for i := 0; i < typ.NumIn(); i++ {
+ in = append(in, typ.In(i))
}
- for i := 0; i < value.Type().NumOut(); i++ {
- out = append(out, value.Type().Out(i))
+ for i := 0; i < typ.NumOut(); i++ {
+ out = append(out, typ.Out(i))
}
if len(in) < len(sig.Args) || len(out) < len(sig.Return) {
- return fmt.Errorf("not enough required parameters: %v", value)
+ return fmt.Errorf("not enough required parameters: %v", typ)
}
+
if len(in) > len(sig.Args)+len(sig.OptArgs) || len(out) >
len(sig.Return)+len(sig.OptReturn) {
- return fmt.Errorf("too many parameters: %v", value)
+ return fmt.Errorf("too many parameters: %v", typ)
}
// (1) Create generic binding. If inconsistent, reject fn. We do not
allow
@@ -144,10 +153,10 @@ func Satisfy(fn interface{}, sig *Signature) error {
if err := matchReq(in[off:], sig.Args); err != nil {
return err
}
- if err := matchReq(out[:len(sig.Return)], sig.Return); err != nil {
+ if err := matchOpt(in[:off], sig.OptArgs, m); err != nil {
return err
}
- if err := matchOpt(in[:off], sig.OptArgs, m); err != nil {
+ if err := matchReq(out[:len(sig.Return)], sig.Return); err != nil {
return err
}
return matchOpt(out[len(sig.Return):], sig.OptReturn, m)
@@ -179,12 +188,21 @@ func matchReq(list, models []reflect.Type) error {
continue
}
if model != t {
- return fmt.Errorf("type mismatch: %v, want %v", t,
model)
+ return &TypeMismatchError{Got: t, Want: model}
}
}
return nil
}
+// TypeMismatchError indicates we didn't get the type we expected.
+type TypeMismatchError struct {
+ Got, Want reflect.Type
+}
+
+func (e *TypeMismatchError) Error() string {
+ return fmt.Sprintf("type mismatch: got %v, want %v", e.Got, e.Want)
+}
+
func matchOpt(list, models []reflect.Type, m map[string]reflect.Type) error {
i := 0
for _, t := range list {
diff --git a/sdks/go/pkg/beam/core/funcx/signature_test.go
b/sdks/go/pkg/beam/core/funcx/signature_test.go
index fecf3c4..ce40ad1 100644
--- a/sdks/go/pkg/beam/core/funcx/signature_test.go
+++ b/sdks/go/pkg/beam/core/funcx/signature_test.go
@@ -206,7 +206,21 @@ func TestSatisfy(t *testing.T) {
for _, test := range tests {
if err := Satisfy(test.Fn, test.Sig); (err == nil) != test.Ok {
- t.Errorf("Satisfy(%v, %v) = %v, want (err==nil)==%v",
reflect.ValueOf(test.Fn).Type(), test.Sig, err, test.Ok)
+ t.Errorf("iface: Satisfy(%v, %v) = %v, want
(err==nil)==%v", reflect.ValueOf(test.Fn).Type(), test.Sig, err, test.Ok)
+ }
+
+ rfn := reflectx.MakeFunc(test.Fn)
+ if err := Satisfy(rfn, test.Sig); (err == nil) != test.Ok {
+ t.Errorf("reflectx.Func: Satisfy(%v, %v) = %v, want
(err==nil)==%v", reflect.ValueOf(test.Fn).Type(), test.Sig, err, test.Ok)
+ }
+
+ fx, err := New(rfn)
+ if err != nil {
+ t.Errorf("Unable to create New Fn from reflectx.Func
%v: %v", rfn.Name(), err)
+ continue
+ }
+ if err := Satisfy(fx, test.Sig); (err == nil) != test.Ok {
+ t.Errorf("*funcx.Fn:Satisfy(%v, %v) = %v, want
(err==nil)==%v", reflect.ValueOf(test.Fn).Type(), test.Sig, err, test.Ok)
}
}
}
diff --git a/sdks/go/pkg/beam/core/graph/fn.go
b/sdks/go/pkg/beam/core/graph/fn.go
index 29c92f8..cc18d30 100644
--- a/sdks/go/pkg/beam/core/graph/fn.go
+++ b/sdks/go/pkg/beam/core/graph/fn.go
@@ -20,6 +20,7 @@ import (
"reflect"
"github.com/apache/beam/sdks/go/pkg/beam/core/funcx"
+ "github.com/apache/beam/sdks/go/pkg/beam/core/typex"
"github.com/apache/beam/sdks/go/pkg/beam/core/util/reflectx"
)
@@ -213,12 +214,12 @@ func AsDoFn(fn *Fn) (*DoFn, error) {
if fn.Fn != nil {
fn.methods[processElementName] = fn.Fn
}
- if err := verifyValidNames(fn, setupName, startBundleName,
processElementName, finishBundleName, teardownName); err != nil {
+ if err := verifyValidNames("graph.AsDoFn", fn, setupName,
startBundleName, processElementName, finishBundleName, teardownName); err !=
nil {
return nil, err
}
if _, ok := fn.methods[processElementName]; !ok {
- return nil, fmt.Errorf("failed to find %v method: %v",
processElementName, fn)
+ return nil, fmt.Errorf("graph.AsDoFn: failed to find %v method:
%v", processElementName, fn)
}
// TODO(herohde) 5/18/2017: validate the signatures, incl. consistency.
@@ -281,26 +282,75 @@ func NewCombineFn(fn interface{}) (*CombineFn, error) {
// AsCombineFn converts a Fn to a CombineFn, if possible.
func AsCombineFn(fn *Fn) (*CombineFn, error) {
+ const fnKind = "graph.AsCombineFn"
if fn.methods == nil {
fn.methods = make(map[string]*funcx.Fn)
}
if fn.Fn != nil {
fn.methods[mergeAccumulatorsName] = fn.Fn
}
- if err := verifyValidNames(fn, setupName, createAccumulatorName,
addInputName, mergeAccumulatorsName, extractOutputName, compactName,
teardownName); err != nil {
+ if err := verifyValidNames(fnKind, fn, setupName,
createAccumulatorName, addInputName, mergeAccumulatorsName, extractOutputName,
compactName, teardownName); err != nil {
return nil, err
}
- if _, ok := fn.methods[mergeAccumulatorsName]; !ok {
- return nil, fmt.Errorf("failed to find %v method: %v",
mergeAccumulatorsName, fn)
+ mergeFn, ok := fn.methods[mergeAccumulatorsName]
+ if !ok {
+ return nil, fmt.Errorf("%v: failed to find required %v method
on type: %v", fnKind, mergeAccumulatorsName, fn.Name())
}
- // TODO(herohde) 5/24/2017: validate the signatures, incl. consistency.
+ // CombineFn methods must satisfy the following:
+ // CreateAccumulator func() (A, error?)
+ // AddInput func(A, I) (A, error?)
+ // MergeAccumulators func(A, A) (A, error?)
+ // ExtractOutput func(A) (O, error?)
+ // This means that the other signatures *must* match the type used in
MergeAccumulators.
+ if len(mergeFn.Ret) <= 0 {
+ return nil, fmt.Errorf("%v: %v requires at least 1 return
value. : %v", fnKind, mergeAccumulatorsName, mergeFn)
+ }
+ accumType := mergeFn.Ret[0].T
+
+ for _, mthd := range []struct {
+ name string
+ sigFunc func(fx *funcx.Fn, accumType reflect.Type)
*funcx.Signature
+ }{
+ {mergeAccumulatorsName, func(fx *funcx.Fn, accumType
reflect.Type) *funcx.Signature {
+ return funcx.Replace(mergeAccumulatorsSig, typex.TType,
accumType)
+ }},
+ {createAccumulatorName, func(fx *funcx.Fn, accumType
reflect.Type) *funcx.Signature {
+ return funcx.Replace(createAccumulatorSig, typex.TType,
accumType)
+ }},
+ {addInputName, func(fx *funcx.Fn, accumType reflect.Type)
*funcx.Signature {
+ // AddInput needs the last parameter type substituted.
+ p := fx.Param[len(fx.Param)-1]
+ aiSig := funcx.Replace(addInputSig, typex.TType,
accumType)
+ return funcx.Replace(aiSig, typex.VType, p.T)
+ }},
+ {extractOutputName, func(fx *funcx.Fn, accumType reflect.Type)
*funcx.Signature {
+ // ExtractOutput needs the first Return type
substituted.
+ r := fx.Ret[0]
+ eoSig := funcx.Replace(extractOutputSig, typex.TType,
accumType)
+ return funcx.Replace(eoSig, typex.WType, r.T)
+ }},
+ } {
+ if err := validateSignature(fnKind, mthd.name, fn, accumType,
mthd.sigFunc); err != nil {
+ return nil, err
+ }
+ }
return (*CombineFn)(fn), nil
}
-func verifyValidNames(fn *Fn, names ...string) error {
+func validateSignature(fnKind, methodName string, fn *Fn, accumType
reflect.Type, sigFunc func(*funcx.Fn, reflect.Type) *funcx.Signature) error {
+ if fx, ok := fn.methods[methodName]; ok {
+ sig := sigFunc(fx, accumType)
+ if err := funcx.Satisfy(fx, sig); err != nil {
+ return &verifyMethodError{fnKind, methodName, err, fn,
accumType, sig}
+ }
+ }
+ return nil
+}
+
+func verifyValidNames(fnKind string, fn *Fn, names ...string) error {
m := make(map[string]bool)
for _, name := range names {
m[name] = true
@@ -308,8 +358,77 @@ func verifyValidNames(fn *Fn, names ...string) error {
for key := range fn.methods {
if !m[key] {
- return fmt.Errorf("unexpected method %v present. Valid
methods are: %v", key, names)
+ return fmt.Errorf("%s: unexpected exported method %v
present. Valid methods are: %v", fnKind, key, names)
}
}
return nil
}
+
+type verifyMethodError struct {
+ // Context for the error.
+ fnKind, methodName string
+ // The triggering error.
+ err error
+
+ fn *Fn
+ accumType reflect.Type
+ sig *funcx.Signature
+}
+
+func (e *verifyMethodError) Error() string {
+ name := e.fn.methods[e.methodName].Fn.Name()
+ if e.fn.Fn == nil {
+ // Methods might be hidden behind reflect.methodValueCall,
which is
+ // not useful to the end user.
+ name = fmt.Sprintf("%s.%s", e.fn.Name(), e.methodName)
+ }
+ typ := e.fn.methods[e.methodName].Fn.Type()
+ switch e.methodName {
+ case mergeAccumulatorsName:
+ // Provide a clearer error for MergeAccumulators, since it's
the root method
+ // for CombineFns.
+ // The root error doesn't matter here since we can't be certain
what the accumulator
+ // type is before mergeAccumulators is verified.
+ return fmt.Sprintf("%v: %s must be a binary merge of
accumulators to be a CombineFn. "+
+ "It is of type \"%v\", but it must be of type
func(context.Context?, A, A) (A, error?) "+
+ "where A is the accumulator type",
+ e.fnKind, name, typ)
+ case createAccumulatorName, addInputName, extractOutputName:
+ // Commonly the accumulator type won't match.
+ if err, ok := e.err.(*funcx.TypeMismatchError); ok && err.Want
== e.accumType {
+ return fmt.Sprintf("%s invalid %v: %s has type \"%v\",
but expected \"%v\" "+
+ "to be the accumulator type \"%v\"; expected a
signature like %v",
+ e.fnKind, e.methodName, name, typ, err.Got,
e.accumType, e.sig)
+ }
+ }
+ return fmt.Sprintf("%s invalid %v %v: got type %v but "+
+ "expected a signature like %v; original error: %v",
+ e.fnKind, e.methodName, name, typ, e.sig, e.err)
+}
+
+var (
+ mergeAccumulatorsSig = &funcx.Signature{
+ OptArgs: []reflect.Type{reflectx.Context},
+ Args: []reflect.Type{typex.TType, typex.TType},
+ Return: []reflect.Type{typex.TType},
+ OptReturn: []reflect.Type{reflectx.Error},
+ }
+ createAccumulatorSig = &funcx.Signature{
+ OptArgs: []reflect.Type{reflectx.Context},
+ Args: []reflect.Type{},
+ Return: []reflect.Type{typex.TType},
+ OptReturn: []reflect.Type{reflectx.Error},
+ }
+ addInputSig = &funcx.Signature{
+ OptArgs: []reflect.Type{reflectx.Context},
+ Args: []reflect.Type{typex.TType, typex.VType},
+ Return: []reflect.Type{typex.TType},
+ OptReturn: []reflect.Type{reflectx.Error},
+ }
+ extractOutputSig = &funcx.Signature{
+ OptArgs: []reflect.Type{reflectx.Context},
+ Args: []reflect.Type{typex.TType},
+ Return: []reflect.Type{typex.WType},
+ OptReturn: []reflect.Type{reflectx.Error},
+ }
+)
diff --git a/sdks/go/pkg/beam/core/graph/fn_test.go
b/sdks/go/pkg/beam/core/graph/fn_test.go
new file mode 100644
index 0000000..d6b8a67
--- /dev/null
+++ b/sdks/go/pkg/beam/core/graph/fn_test.go
@@ -0,0 +1,311 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package graph
+
+import (
+ "context"
+ "reflect"
+ "testing"
+)
+
+func TestNewCombineFn(t *testing.T) {
+ t.Run("valid", func(t *testing.T) {
+ tests := []struct {
+ cfn interface{}
+ }{
+ {cfn: func(int, int) int { return 0 }},
+ {cfn: func(string, string) string { return "" }},
+ {cfn: func(MyAccum, MyAccum) MyAccum { return MyAccum{}
}},
+ {cfn: func(MyAccum, MyAccum) (MyAccum, error) { return
MyAccum{}, nil }},
+ {cfn: func(context.Context, MyAccum, MyAccum) MyAccum {
return MyAccum{} }},
+ {cfn: func(context.Context, MyAccum, MyAccum) (MyAccum,
error) { return MyAccum{}, nil }},
+ {cfn: &GoodCombineFn{}},
+ {cfn: &GoodWErrorCombineFn{}},
+ {cfn: &GoodWContextCombineFn{}},
+ {cfn: &GoodCombineFnUnexportedExtraMethod{}},
+ }
+
+ for _, test := range tests {
+ t.Run(reflect.TypeOf(test.cfn).String(), func(t
*testing.T) {
+ if _, err := NewCombineFn(test.cfn); err != nil
{
+ t.Fatalf("NewCombineFn failed: %v", err)
+ }
+ })
+ }
+ })
+ t.Run("invalid", func(t *testing.T) {
+ tests := []struct {
+ cfn interface{}
+ }{
+ // Validate MergeAccumulator errors
+ {cfn: func() int { return 0 }},
+ {cfn: func(int, int) {}},
+ {cfn: func(int, int) string { return "" }},
+ {cfn: func(string, string) int { return 0 }},
+ {cfn: func(int, string) int { return 0 }},
+ {cfn: func(string, int) int { return 0 }},
+ {cfn: func(string, int) (int, error) { return 0, nil }},
+ {cfn: &BadCombineFnNoMergeAccumulators{}},
+ {cfn: &BadCombineFnNonBinaryMergeAccumulators{}},
+ // Validate accumulator type mismatches
+ {cfn: &BadCombineFnMisMatchedCreateAccumulator{}},
+ {cfn: &BadCombineFnMisMatchedAddInputIn{}},
+ {cfn: &BadCombineFnMisMatchedAddInputOut{}},
+ {cfn: &BadCombineFnMisMatchedAddInputBoth{}},
+ {cfn: &BadCombineFnMisMatchedExtractOutput{}},
+ // Validate signatures
+ {cfn: &BadCombineFnInvalidCreateAccumulator1{}},
+ {cfn: &BadCombineFnInvalidCreateAccumulator2{}},
+ {cfn: &BadCombineFnInvalidCreateAccumulator3{}},
+ {cfn: &BadCombineFnInvalidCreateAccumulator4{}},
+ {cfn: &BadCombineFnInvalidAddInput1{}},
+ {cfn: &BadCombineFnInvalidAddInput2{}},
+ {cfn: &BadCombineFnInvalidAddInput3{}},
+ {cfn: &BadCombineFnInvalidAddInput4{}},
+ {cfn: &BadCombineFnInvalidExtractOutput1{}},
+ {cfn: &BadCombineFnInvalidExtractOutput2{}},
+ {cfn: &BadCombineFnInvalidExtractOutput3{}},
+ {cfn: &BadCombineFnExtraExportedMethod{}},
+ }
+ for _, test := range tests {
+ t.Run(reflect.TypeOf(test.cfn).String(), func(t
*testing.T) {
+ if cfn, err := NewCombineFn(test.cfn); err !=
nil {
+ // Note to Developer: To work on
improving the error messages, use t.Errorf instead!
+ t.Logf("NewCombineFn failed as
expected:\n%v", err)
+ } else {
+ t.Errorf("AsCombineFn(%v) = %v, want
failure", cfn.Name(), cfn)
+ }
+ })
+ }
+ })
+}
+
+// Do not copy. The following types are for testing signatures only.
+// They are not working examples.
+// Keep all test functions Above this point.
+type MyAccum struct{}
+
+// Examples of correct CombineFn signatures
+
+type GoodCombineFn struct{}
+
+func (fn *GoodCombineFn) MergeAccumulators(MyAccum, MyAccum) MyAccum {
+ return MyAccum{}
+}
+
+func (fn *GoodCombineFn) CreateAccumulator() MyAccum {
+ return MyAccum{}
+}
+
+func (fn *GoodCombineFn) AddInput(MyAccum, int) MyAccum {
+ return MyAccum{}
+}
+
+func (fn *GoodCombineFn) ExtractOutput(MyAccum) int64 {
+ return 0
+}
+
+type GoodWErrorCombineFn struct{}
+
+func (fn *GoodWErrorCombineFn) MergeAccumulators(int, int) (int, error) {
+ return 0, nil
+}
+
+type GoodWContextCombineFn struct{}
+
+func (fn *GoodWContextCombineFn) MergeAccumulators(context.Context, MyAccum,
MyAccum) MyAccum {
+ return MyAccum{}
+}
+
+func (fn *GoodWContextCombineFn) CreateAccumulator(context.Context) MyAccum {
+ return MyAccum{}
+}
+
+func (fn *GoodWContextCombineFn) AddInput(context.Context, MyAccum, int)
MyAccum {
+ return MyAccum{}
+}
+
+func (fn *GoodWContextCombineFn) ExtractOutput(context.Context, MyAccum) int64
{
+ return 0
+}
+
+type GoodCombineFnUnexportedExtraMethod struct {
+ *GoodCombineFn
+}
+
+func (fn *GoodCombineFnUnexportedExtraMethod)
unexportedExtraMethod(context.Context, string) string {
+ return ""
+}
+
+// Examples of incorrect CombineFn signatures.
+// Embedding *GoodCombineFn avoids repetitive MergeAccumulators signatures
when desired.
+// The immeadiately following examples are relating to accumulator mismatches.
+
+type BadCombineFnNoMergeAccumulators struct{}
+
+func (fn *BadCombineFnNoMergeAccumulators) CreateAccumulator() string { return
"" }
+
+type BadCombineFnNonBinaryMergeAccumulators struct {
+ *GoodCombineFn
+}
+
+func (fn *BadCombineFnNonBinaryMergeAccumulators) MergeAccumulators(int,
string) int {
+ return 0
+}
+
+type BadCombineFnMisMatchedCreateAccumulator struct {
+ *GoodCombineFn
+}
+
+func (fn *BadCombineFnMisMatchedCreateAccumulator) CreateAccumulator() string {
+ return ""
+}
+
+type BadCombineFnMisMatchedAddInputIn struct {
+ *GoodCombineFn
+}
+
+func (fn *BadCombineFnMisMatchedAddInputIn) AddInput(string, int) MyAccum {
+ return MyAccum{}
+}
+
+type BadCombineFnMisMatchedAddInputOut struct {
+ *GoodCombineFn
+}
+
+func (fn *BadCombineFnMisMatchedAddInputOut) AddInput(MyAccum, int) string {
+ return ""
+}
+
+type BadCombineFnMisMatchedAddInputBoth struct {
+ *GoodCombineFn
+}
+
+func (fn *BadCombineFnMisMatchedAddInputBoth) AddInput(string, int) string {
+ return ""
+}
+
+type BadCombineFnMisMatchedExtractOutput struct {
+ *GoodCombineFn
+}
+
+func (fn *BadCombineFnMisMatchedExtractOutput) ExtractOutput(string) int {
+ return 0
+}
+
+// Examples of incorrect CreateAccumulator signatures
+
+type BadCombineFnInvalidCreateAccumulator1 struct {
+ *GoodCombineFn
+}
+
+func (fn *BadCombineFnInvalidCreateAccumulator1)
CreateAccumulator(context.Context, string) int {
+ return 0
+}
+
+type BadCombineFnInvalidCreateAccumulator2 struct {
+ *GoodCombineFn
+}
+
+func (fn *BadCombineFnInvalidCreateAccumulator2) CreateAccumulator(string) int
{
+ return 0
+}
+
+type BadCombineFnInvalidCreateAccumulator3 struct {
+ *GoodCombineFn
+}
+
+func (fn *BadCombineFnInvalidCreateAccumulator3) CreateAccumulator() (MyAccum,
string) {
+ return MyAccum{}, ""
+}
+
+type BadCombineFnInvalidCreateAccumulator4 struct {
+ *GoodCombineFn
+}
+
+func (fn *BadCombineFnInvalidCreateAccumulator4) CreateAccumulator() (string,
MyAccum) {
+ return "", MyAccum{}
+}
+
+// Examples of incorrect AddInput signatures
+
+type BadCombineFnInvalidAddInput1 struct {
+ *GoodCombineFn
+}
+
+func (fn *BadCombineFnInvalidAddInput1) AddInput(context.Context, string) int {
+ return 0
+}
+
+type BadCombineFnInvalidAddInput2 struct {
+ *GoodCombineFn
+}
+
+func (fn *BadCombineFnInvalidAddInput2) AddInput(string) int {
+ return 0
+}
+
+type BadCombineFnInvalidAddInput3 struct {
+ *GoodCombineFn
+}
+
+func (fn *BadCombineFnInvalidAddInput3) AddInput(context.Context, string,
string, string) int {
+ return 0
+}
+
+type BadCombineFnInvalidAddInput4 struct {
+ *GoodCombineFn
+}
+
+func (fn *BadCombineFnInvalidAddInput4) AddInput(MyAccum, string) (int, int,
int) {
+ return 0, 0, 0
+}
+
+// Examples of incorrect ExtractOutput signatures
+
+type BadCombineFnInvalidExtractOutput1 struct {
+ *GoodCombineFn
+}
+
+func (fn *BadCombineFnInvalidExtractOutput1) ExtractOutput(MyAccum, string)
(int, int, int) {
+ return 0, 0, 0
+}
+
+type BadCombineFnInvalidExtractOutput2 struct {
+ *GoodCombineFn
+}
+
+func (fn *BadCombineFnInvalidExtractOutput2) ExtractOutput() (int, int, int) {
+ return 0, 0, 0
+}
+
+type BadCombineFnInvalidExtractOutput3 struct {
+ *GoodCombineFn
+}
+
+func (fn *BadCombineFnInvalidExtractOutput3) ExtractOutput(context.Context,
MyAccum, int) int {
+ return 0
+}
+
+// Other CombineFn Errors
+
+type BadCombineFnExtraExportedMethod struct {
+ *GoodCombineFn
+}
+
+func (fn *BadCombineFnExtraExportedMethod) ExtraMethod(string) int {
+ return 0
+}
diff --git a/sdks/go/pkg/beam/transforms/stats/mean.go
b/sdks/go/pkg/beam/transforms/stats/mean.go
index 9d68231..3b74cde 100644
--- a/sdks/go/pkg/beam/transforms/stats/mean.go
+++ b/sdks/go/pkg/beam/transforms/stats/mean.go
@@ -74,13 +74,8 @@ func (f *meanFn) AddInput(a meanAccum, val beam.T) meanAccum
{
return a
}
-func (f *meanFn) MergeAccumulators(list []meanAccum) meanAccum {
- var ret meanAccum
- for _, a := range list {
- ret.Count += a.Count
- ret.Sum += a.Sum
- }
- return ret
+func (f *meanFn) MergeAccumulators(a, b meanAccum) meanAccum {
+ return meanAccum{Count: a.Count + b.Count, Sum: a.Sum + b.Sum}
}
func (f *meanFn) ExtractOutput(a meanAccum) float64 {
diff --git a/sdks/go/pkg/beam/transforms/stats/stats.shims.go
b/sdks/go/pkg/beam/transforms/stats/stats.shims.go
index 3af95fb..cd2a95a 100644
--- a/sdks/go/pkg/beam/transforms/stats/stats.shims.go
+++ b/sdks/go/pkg/beam/transforms/stats/stats.shims.go
@@ -68,41 +68,41 @@ func init() {
runtime.RegisterType(reflect.TypeOf((*meanAccum)(nil)).Elem())
runtime.RegisterType(reflect.TypeOf((*meanFn)(nil)).Elem())
reflectx.RegisterStructWrapper(reflect.TypeOf((*meanFn)(nil)).Elem(),
wrapMakerMeanFn)
- reflectx.RegisterFunc(reflect.TypeOf((*func(float32, float32)
float32)(nil)).Elem(), funcMakerFloat32Float32ГFloat32)
- reflectx.RegisterFunc(reflect.TypeOf((*func(float64, float64)
float64)(nil)).Elem(), funcMakerFloat64Float64ГFloat64)
- reflectx.RegisterFunc(reflect.TypeOf((*func(int16, int16)
int16)(nil)).Elem(), funcMakerInt16Int16ГInt16)
- reflectx.RegisterFunc(reflect.TypeOf((*func(int32, int32)
int32)(nil)).Elem(), funcMakerInt32Int32ГInt32)
- reflectx.RegisterFunc(reflect.TypeOf((*func(int64, int64)
int64)(nil)).Elem(), funcMakerInt64Int64ГInt64)
- reflectx.RegisterFunc(reflect.TypeOf((*func(int8, int8)
int8)(nil)).Elem(), funcMakerInt8Int8ГInt8)
- reflectx.RegisterFunc(reflect.TypeOf((*func(int, int)
int)(nil)).Elem(), funcMakerIntIntГInt)
- reflectx.RegisterFunc(reflect.TypeOf((*func(meanAccum, typex.T)
meanAccum)(nil)).Elem(), funcMakerMeanAccumTypex۰TГMeanAccum)
- reflectx.RegisterFunc(reflect.TypeOf((*func(meanAccum)
float64)(nil)).Elem(), funcMakerMeanAccumГFloat64)
- reflectx.RegisterFunc(reflect.TypeOf((*func([]meanAccum)
meanAccum)(nil)).Elem(), funcMakerSliceOfMeanAccumГMeanAccum)
- reflectx.RegisterFunc(reflect.TypeOf((*func(typex.T) (typex.T,
int))(nil)).Elem(), funcMakerTypex۰TГTypex۰TInt)
- reflectx.RegisterFunc(reflect.TypeOf((*func(uint16, uint16)
uint16)(nil)).Elem(), funcMakerUint16Uint16ГUint16)
- reflectx.RegisterFunc(reflect.TypeOf((*func(uint32, uint32)
uint32)(nil)).Elem(), funcMakerUint32Uint32ГUint32)
- reflectx.RegisterFunc(reflect.TypeOf((*func(uint64, uint64)
uint64)(nil)).Elem(), funcMakerUint64Uint64ГUint64)
- reflectx.RegisterFunc(reflect.TypeOf((*func(uint8, uint8)
uint8)(nil)).Elem(), funcMakerUint8Uint8ГUint8)
- reflectx.RegisterFunc(reflect.TypeOf((*func(uint, uint)
uint)(nil)).Elem(), funcMakerUintUintГUint)
- reflectx.RegisterFunc(reflect.TypeOf((*func() meanAccum)(nil)).Elem(),
funcMakerГMeanAccum)
+ reflectx.RegisterFunc(reflect.TypeOf((*func(float32,float32)
(float32))(nil)).Elem(), funcMakerFloat32Float32ГFloat32)
+ reflectx.RegisterFunc(reflect.TypeOf((*func(float64,float64)
(float64))(nil)).Elem(), funcMakerFloat64Float64ГFloat64)
+ reflectx.RegisterFunc(reflect.TypeOf((*func(int16,int16)
(int16))(nil)).Elem(), funcMakerInt16Int16ГInt16)
+ reflectx.RegisterFunc(reflect.TypeOf((*func(int32,int32)
(int32))(nil)).Elem(), funcMakerInt32Int32ГInt32)
+ reflectx.RegisterFunc(reflect.TypeOf((*func(int64,int64)
(int64))(nil)).Elem(), funcMakerInt64Int64ГInt64)
+ reflectx.RegisterFunc(reflect.TypeOf((*func(int8,int8)
(int8))(nil)).Elem(), funcMakerInt8Int8ГInt8)
+ reflectx.RegisterFunc(reflect.TypeOf((*func(int,int)
(int))(nil)).Elem(), funcMakerIntIntГInt)
+ reflectx.RegisterFunc(reflect.TypeOf((*func(meanAccum,meanAccum)
(meanAccum))(nil)).Elem(), funcMakerMeanAccumMeanAccumГMeanAccum)
+ reflectx.RegisterFunc(reflect.TypeOf((*func(meanAccum,typex.T)
(meanAccum))(nil)).Elem(), funcMakerMeanAccumTypex۰TГMeanAccum)
+ reflectx.RegisterFunc(reflect.TypeOf((*func(meanAccum)
(float64))(nil)).Elem(), funcMakerMeanAccumГFloat64)
+ reflectx.RegisterFunc(reflect.TypeOf((*func(typex.T)
(typex.T,int))(nil)).Elem(), funcMakerTypex۰TГTypex۰TInt)
+ reflectx.RegisterFunc(reflect.TypeOf((*func(uint16,uint16)
(uint16))(nil)).Elem(), funcMakerUint16Uint16ГUint16)
+ reflectx.RegisterFunc(reflect.TypeOf((*func(uint32,uint32)
(uint32))(nil)).Elem(), funcMakerUint32Uint32ГUint32)
+ reflectx.RegisterFunc(reflect.TypeOf((*func(uint64,uint64)
(uint64))(nil)).Elem(), funcMakerUint64Uint64ГUint64)
+ reflectx.RegisterFunc(reflect.TypeOf((*func(uint8,uint8)
(uint8))(nil)).Elem(), funcMakerUint8Uint8ГUint8)
+ reflectx.RegisterFunc(reflect.TypeOf((*func(uint,uint)
(uint))(nil)).Elem(), funcMakerUintUintГUint)
+ reflectx.RegisterFunc(reflect.TypeOf((*func()
(meanAccum))(nil)).Elem(), funcMakerГMeanAccum)
}
func wrapMakerMeanFn(fn interface{}) map[string]reflectx.Func {
dfn := fn.(*meanFn)
return map[string]reflectx.Func{
- "AddInput": reflectx.MakeFunc(func(a0 meanAccum, a1
typex.T) meanAccum { return dfn.AddInput(a0, a1) }),
- "CreateAccumulator": reflectx.MakeFunc(func() meanAccum {
return dfn.CreateAccumulator() }),
- "ExtractOutput": reflectx.MakeFunc(func(a0 meanAccum)
float64 { return dfn.ExtractOutput(a0) }),
- "MergeAccumulators": reflectx.MakeFunc(func(a0 []meanAccum)
meanAccum { return dfn.MergeAccumulators(a0) }),
+ "AddInput": reflectx.MakeFunc(func(a0 meanAccum, a1 typex.T)
(meanAccum) { return dfn.AddInput(a0, a1) }),
+ "CreateAccumulator": reflectx.MakeFunc(func() (meanAccum) {
return dfn.CreateAccumulator() }),
+ "ExtractOutput": reflectx.MakeFunc(func(a0 meanAccum) (float64)
{ return dfn.ExtractOutput(a0) }),
+ "MergeAccumulators": reflectx.MakeFunc(func(a0 meanAccum, a1
meanAccum) (meanAccum) { return dfn.MergeAccumulators(a0, a1) }),
}
}
type callerFloat32Float32ГFloat32 struct {
- fn func(float32, float32) float32
+ fn func(float32,float32) (float32)
}
func funcMakerFloat32Float32ГFloat32(fn interface{}) reflectx.Func {
- f := fn.(func(float32, float32) float32)
+ f := fn.(func(float32,float32) (float32))
return &callerFloat32Float32ГFloat32{fn: f}
}
@@ -119,16 +119,16 @@ func (c *callerFloat32Float32ГFloat32) Call(args
[]interface{}) []interface{} {
return []interface{}{out0}
}
-func (c *callerFloat32Float32ГFloat32) Call2x1(arg0, arg1 interface{})
interface{} {
+func (c *callerFloat32Float32ГFloat32) Call2x1(arg0, arg1 interface{})
(interface{}) {
return c.fn(arg0.(float32), arg1.(float32))
}
type callerFloat64Float64ГFloat64 struct {
- fn func(float64, float64) float64
+ fn func(float64,float64) (float64)
}
func funcMakerFloat64Float64ГFloat64(fn interface{}) reflectx.Func {
- f := fn.(func(float64, float64) float64)
+ f := fn.(func(float64,float64) (float64))
return &callerFloat64Float64ГFloat64{fn: f}
}
@@ -145,16 +145,16 @@ func (c *callerFloat64Float64ГFloat64) Call(args
[]interface{}) []interface{} {
return []interface{}{out0}
}
-func (c *callerFloat64Float64ГFloat64) Call2x1(arg0, arg1 interface{})
interface{} {
+func (c *callerFloat64Float64ГFloat64) Call2x1(arg0, arg1 interface{})
(interface{}) {
return c.fn(arg0.(float64), arg1.(float64))
}
type callerInt16Int16ГInt16 struct {
- fn func(int16, int16) int16
+ fn func(int16,int16) (int16)
}
func funcMakerInt16Int16ГInt16(fn interface{}) reflectx.Func {
- f := fn.(func(int16, int16) int16)
+ f := fn.(func(int16,int16) (int16))
return &callerInt16Int16ГInt16{fn: f}
}
@@ -171,16 +171,16 @@ func (c *callerInt16Int16ГInt16) Call(args []interface{})
[]interface{} {
return []interface{}{out0}
}
-func (c *callerInt16Int16ГInt16) Call2x1(arg0, arg1 interface{}) interface{} {
+func (c *callerInt16Int16ГInt16) Call2x1(arg0, arg1 interface{}) (interface{})
{
return c.fn(arg0.(int16), arg1.(int16))
}
type callerInt32Int32ГInt32 struct {
- fn func(int32, int32) int32
+ fn func(int32,int32) (int32)
}
func funcMakerInt32Int32ГInt32(fn interface{}) reflectx.Func {
- f := fn.(func(int32, int32) int32)
+ f := fn.(func(int32,int32) (int32))
return &callerInt32Int32ГInt32{fn: f}
}
@@ -197,16 +197,16 @@ func (c *callerInt32Int32ГInt32) Call(args []interface{})
[]interface{} {
return []interface{}{out0}
}
-func (c *callerInt32Int32ГInt32) Call2x1(arg0, arg1 interface{}) interface{} {
+func (c *callerInt32Int32ГInt32) Call2x1(arg0, arg1 interface{}) (interface{})
{
return c.fn(arg0.(int32), arg1.(int32))
}
type callerInt64Int64ГInt64 struct {
- fn func(int64, int64) int64
+ fn func(int64,int64) (int64)
}
func funcMakerInt64Int64ГInt64(fn interface{}) reflectx.Func {
- f := fn.(func(int64, int64) int64)
+ f := fn.(func(int64,int64) (int64))
return &callerInt64Int64ГInt64{fn: f}
}
@@ -223,16 +223,16 @@ func (c *callerInt64Int64ГInt64) Call(args []interface{})
[]interface{} {
return []interface{}{out0}
}
-func (c *callerInt64Int64ГInt64) Call2x1(arg0, arg1 interface{}) interface{} {
+func (c *callerInt64Int64ГInt64) Call2x1(arg0, arg1 interface{}) (interface{})
{
return c.fn(arg0.(int64), arg1.(int64))
}
type callerInt8Int8ГInt8 struct {
- fn func(int8, int8) int8
+ fn func(int8,int8) (int8)
}
func funcMakerInt8Int8ГInt8(fn interface{}) reflectx.Func {
- f := fn.(func(int8, int8) int8)
+ f := fn.(func(int8,int8) (int8))
return &callerInt8Int8ГInt8{fn: f}
}
@@ -249,16 +249,16 @@ func (c *callerInt8Int8ГInt8) Call(args []interface{})
[]interface{} {
return []interface{}{out0}
}
-func (c *callerInt8Int8ГInt8) Call2x1(arg0, arg1 interface{}) interface{} {
+func (c *callerInt8Int8ГInt8) Call2x1(arg0, arg1 interface{}) (interface{}) {
return c.fn(arg0.(int8), arg1.(int8))
}
type callerIntIntГInt struct {
- fn func(int, int) int
+ fn func(int,int) (int)
}
func funcMakerIntIntГInt(fn interface{}) reflectx.Func {
- f := fn.(func(int, int) int)
+ f := fn.(func(int,int) (int))
return &callerIntIntГInt{fn: f}
}
@@ -275,16 +275,42 @@ func (c *callerIntIntГInt) Call(args []interface{})
[]interface{} {
return []interface{}{out0}
}
-func (c *callerIntIntГInt) Call2x1(arg0, arg1 interface{}) interface{} {
+func (c *callerIntIntГInt) Call2x1(arg0, arg1 interface{}) (interface{}) {
return c.fn(arg0.(int), arg1.(int))
}
+type callerMeanAccumMeanAccumГMeanAccum struct {
+ fn func(meanAccum,meanAccum) (meanAccum)
+}
+
+func funcMakerMeanAccumMeanAccumГMeanAccum(fn interface{}) reflectx.Func {
+ f := fn.(func(meanAccum,meanAccum) (meanAccum))
+ return &callerMeanAccumMeanAccumГMeanAccum{fn: f}
+}
+
+func (c *callerMeanAccumMeanAccumГMeanAccum) Name() string {
+ return reflectx.FunctionName(c.fn)
+}
+
+func (c *callerMeanAccumMeanAccumГMeanAccum) Type() reflect.Type {
+ return reflect.TypeOf(c.fn)
+}
+
+func (c *callerMeanAccumMeanAccumГMeanAccum) Call(args []interface{})
[]interface{} {
+ out0 := c.fn(args[0].(meanAccum), args[1].(meanAccum))
+ return []interface{}{out0}
+}
+
+func (c *callerMeanAccumMeanAccumГMeanAccum) Call2x1(arg0, arg1 interface{})
(interface{}) {
+ return c.fn(arg0.(meanAccum), arg1.(meanAccum))
+}
+
type callerMeanAccumTypex۰TГMeanAccum struct {
- fn func(meanAccum, typex.T) meanAccum
+ fn func(meanAccum,typex.T) (meanAccum)
}
func funcMakerMeanAccumTypex۰TГMeanAccum(fn interface{}) reflectx.Func {
- f := fn.(func(meanAccum, typex.T) meanAccum)
+ f := fn.(func(meanAccum,typex.T) (meanAccum))
return &callerMeanAccumTypex۰TГMeanAccum{fn: f}
}
@@ -301,16 +327,16 @@ func (c *callerMeanAccumTypex۰TГMeanAccum) Call(args
[]interface{}) []interfac
return []interface{}{out0}
}
-func (c *callerMeanAccumTypex۰TГMeanAccum) Call2x1(arg0, arg1 interface{})
interface{} {
+func (c *callerMeanAccumTypex۰TГMeanAccum) Call2x1(arg0, arg1 interface{})
(interface{}) {
return c.fn(arg0.(meanAccum), arg1.(typex.T))
}
type callerMeanAccumГFloat64 struct {
- fn func(meanAccum) float64
+ fn func(meanAccum) (float64)
}
func funcMakerMeanAccumГFloat64(fn interface{}) reflectx.Func {
- f := fn.(func(meanAccum) float64)
+ f := fn.(func(meanAccum) (float64))
return &callerMeanAccumГFloat64{fn: f}
}
@@ -327,42 +353,16 @@ func (c *callerMeanAccumГFloat64) Call(args
[]interface{}) []interface{} {
return []interface{}{out0}
}
-func (c *callerMeanAccumГFloat64) Call1x1(arg0 interface{}) interface{} {
+func (c *callerMeanAccumГFloat64) Call1x1(arg0 interface{}) (interface{}) {
return c.fn(arg0.(meanAccum))
}
-type callerSliceOfMeanAccumГMeanAccum struct {
- fn func([]meanAccum) meanAccum
-}
-
-func funcMakerSliceOfMeanAccumГMeanAccum(fn interface{}) reflectx.Func {
- f := fn.(func([]meanAccum) meanAccum)
- return &callerSliceOfMeanAccumГMeanAccum{fn: f}
-}
-
-func (c *callerSliceOfMeanAccumГMeanAccum) Name() string {
- return reflectx.FunctionName(c.fn)
-}
-
-func (c *callerSliceOfMeanAccumГMeanAccum) Type() reflect.Type {
- return reflect.TypeOf(c.fn)
-}
-
-func (c *callerSliceOfMeanAccumГMeanAccum) Call(args []interface{})
[]interface{} {
- out0 := c.fn(args[0].([]meanAccum))
- return []interface{}{out0}
-}
-
-func (c *callerSliceOfMeanAccumГMeanAccum) Call1x1(arg0 interface{})
interface{} {
- return c.fn(arg0.([]meanAccum))
-}
-
type callerTypex۰TГTypex۰TInt struct {
- fn func(typex.T) (typex.T, int)
+ fn func(typex.T) (typex.T,int)
}
func funcMakerTypex۰TГTypex۰TInt(fn interface{}) reflectx.Func {
- f := fn.(func(typex.T) (typex.T, int))
+ f := fn.(func(typex.T) (typex.T,int))
return &callerTypex۰TГTypex۰TInt{fn: f}
}
@@ -384,11 +384,11 @@ func (c *callerTypex۰TГTypex۰TInt) Call1x2(arg0
interface{}) (interface{}, in
}
type callerUint16Uint16ГUint16 struct {
- fn func(uint16, uint16) uint16
+ fn func(uint16,uint16) (uint16)
}
func funcMakerUint16Uint16ГUint16(fn interface{}) reflectx.Func {
- f := fn.(func(uint16, uint16) uint16)
+ f := fn.(func(uint16,uint16) (uint16))
return &callerUint16Uint16ГUint16{fn: f}
}
@@ -405,16 +405,16 @@ func (c *callerUint16Uint16ГUint16) Call(args
[]interface{}) []interface{} {
return []interface{}{out0}
}
-func (c *callerUint16Uint16ГUint16) Call2x1(arg0, arg1 interface{})
interface{} {
+func (c *callerUint16Uint16ГUint16) Call2x1(arg0, arg1 interface{})
(interface{}) {
return c.fn(arg0.(uint16), arg1.(uint16))
}
type callerUint32Uint32ГUint32 struct {
- fn func(uint32, uint32) uint32
+ fn func(uint32,uint32) (uint32)
}
func funcMakerUint32Uint32ГUint32(fn interface{}) reflectx.Func {
- f := fn.(func(uint32, uint32) uint32)
+ f := fn.(func(uint32,uint32) (uint32))
return &callerUint32Uint32ГUint32{fn: f}
}
@@ -431,16 +431,16 @@ func (c *callerUint32Uint32ГUint32) Call(args
[]interface{}) []interface{} {
return []interface{}{out0}
}
-func (c *callerUint32Uint32ГUint32) Call2x1(arg0, arg1 interface{})
interface{} {
+func (c *callerUint32Uint32ГUint32) Call2x1(arg0, arg1 interface{})
(interface{}) {
return c.fn(arg0.(uint32), arg1.(uint32))
}
type callerUint64Uint64ГUint64 struct {
- fn func(uint64, uint64) uint64
+ fn func(uint64,uint64) (uint64)
}
func funcMakerUint64Uint64ГUint64(fn interface{}) reflectx.Func {
- f := fn.(func(uint64, uint64) uint64)
+ f := fn.(func(uint64,uint64) (uint64))
return &callerUint64Uint64ГUint64{fn: f}
}
@@ -457,16 +457,16 @@ func (c *callerUint64Uint64ГUint64) Call(args
[]interface{}) []interface{} {
return []interface{}{out0}
}
-func (c *callerUint64Uint64ГUint64) Call2x1(arg0, arg1 interface{})
interface{} {
+func (c *callerUint64Uint64ГUint64) Call2x1(arg0, arg1 interface{})
(interface{}) {
return c.fn(arg0.(uint64), arg1.(uint64))
}
type callerUint8Uint8ГUint8 struct {
- fn func(uint8, uint8) uint8
+ fn func(uint8,uint8) (uint8)
}
func funcMakerUint8Uint8ГUint8(fn interface{}) reflectx.Func {
- f := fn.(func(uint8, uint8) uint8)
+ f := fn.(func(uint8,uint8) (uint8))
return &callerUint8Uint8ГUint8{fn: f}
}
@@ -483,16 +483,16 @@ func (c *callerUint8Uint8ГUint8) Call(args []interface{})
[]interface{} {
return []interface{}{out0}
}
-func (c *callerUint8Uint8ГUint8) Call2x1(arg0, arg1 interface{}) interface{} {
+func (c *callerUint8Uint8ГUint8) Call2x1(arg0, arg1 interface{}) (interface{})
{
return c.fn(arg0.(uint8), arg1.(uint8))
}
type callerUintUintГUint struct {
- fn func(uint, uint) uint
+ fn func(uint,uint) (uint)
}
func funcMakerUintUintГUint(fn interface{}) reflectx.Func {
- f := fn.(func(uint, uint) uint)
+ f := fn.(func(uint,uint) (uint))
return &callerUintUintГUint{fn: f}
}
@@ -509,16 +509,16 @@ func (c *callerUintUintГUint) Call(args []interface{})
[]interface{} {
return []interface{}{out0}
}
-func (c *callerUintUintГUint) Call2x1(arg0, arg1 interface{}) interface{} {
+func (c *callerUintUintГUint) Call2x1(arg0, arg1 interface{}) (interface{}) {
return c.fn(arg0.(uint), arg1.(uint))
}
type callerГMeanAccum struct {
- fn func() meanAccum
+ fn func() (meanAccum)
}
func funcMakerГMeanAccum(fn interface{}) reflectx.Func {
- f := fn.(func() meanAccum)
+ f := fn.(func() (meanAccum))
return &callerГMeanAccum{fn: f}
}
@@ -535,8 +535,9 @@ func (c *callerГMeanAccum) Call(args []interface{})
[]interface{} {
return []interface{}{out0}
}
-func (c *callerГMeanAccum) Call0x1() interface{} {
+func (c *callerГMeanAccum) Call0x1() (interface{}) {
return c.fn()
}
+
// DO NOT MODIFY: GENERATED CODE