From 164acaed8876c96f0b9f726fd4fdc5e59f79aad9 Mon Sep 17 00:00:00 2001 From: Adam Scarr Date: Sat, 14 Jul 2018 15:56:46 +1000 Subject: [PATCH] validate method return types --- codegen/input_build.go | 6 +- codegen/object_build.go | 7 +- codegen/testdata/recursive.go | 2 +- codegen/util.go | 183 +++++++++++++++++------- example/chat/generated.go | 60 ++------ example/dataloader/generated.go | 60 ++------ example/scalars/generated.go | 60 ++------ example/selection/generated.go | 60 ++------ example/starwars/generated.go | 60 ++------ example/todo/generated.go | 60 ++------ main.go | 7 + neelance/introspection/introspection.go | 68 ++++----- test/generated.go | 112 ++++++++------- test/models-go/element.go | 4 + test/resolvers_test.go | 4 + test/schema.graphql | 5 +- 16 files changed, 328 insertions(+), 430 deletions(-) diff --git a/codegen/input_build.go b/codegen/input_build.go index 81da1ffe52d..98b25b8b21d 100644 --- a/codegen/input_build.go +++ b/codegen/input_build.go @@ -27,9 +27,9 @@ func (cfg *Config) buildInputs(namedTypes NamedTypes, prog *loader.Program, impo } if def != nil { input.Marshaler = buildInputMarshaler(typ, def) - err = bindObject(def.Type(), input, imports) - if err != nil { - return nil, err + bindErrs := bindObject(def.Type(), input, imports) + if len(bindErrs) > 0 { + return nil, bindErrs } } diff --git a/codegen/object_build.go b/codegen/object_build.go index 0a4005872b3..0ef40feff21 100644 --- a/codegen/object_build.go +++ b/codegen/object_build.go @@ -1,6 +1,7 @@ package codegen import ( + "log" "sort" "strings" @@ -25,9 +26,9 @@ func (cfg *Config) buildObjects(types NamedTypes, prog *loader.Program, imports return nil, err } if def != nil { - err = bindObject(def.Type(), obj, imports) - if err != nil { - return nil, err + for _, bindErr := range bindObject(def.Type(), obj, imports) { + log.Println(bindErr.Error()) + log.Println(" Adding resolver method") } } diff --git a/codegen/testdata/recursive.go b/codegen/testdata/recursive.go index 4e70332f8fe..65854f7721b 100644 --- a/codegen/testdata/recursive.go +++ b/codegen/testdata/recursive.go @@ -1,5 +1,5 @@ package testdata type RecursiveInputSlice struct { - Self *[]*RecursiveInputSlice + Self []RecursiveInputSlice } diff --git a/codegen/util.go b/codegen/util.go index 03e8e51d1d5..5ff41074324 100644 --- a/codegen/util.go +++ b/codegen/util.go @@ -1,6 +1,7 @@ package codegen import ( + "fmt" "go/types" "regexp" "strings" @@ -131,71 +132,155 @@ func findField(typ *types.Struct, name string) *types.Var { return nil } -func bindObject(t types.Type, object *Object, imports *Imports) error { +type BindError struct { + object *Object + field *Field + typ types.Type + methodErr error + varErr error +} + +func (b BindError) Error() string { + return fmt.Sprintf( + "Unable to bind %s.%s to %s\n %s\n %s", + b.object.GQLType, + b.field.GQLName, + b.typ.String(), + b.methodErr.Error(), + b.varErr.Error(), + ) +} + +type BindErrors []BindError + +func (b BindErrors) Error() string { + var errs []string + for _, err := range b { + errs = append(errs, err.Error()) + } + return strings.Join(errs, "\n\n") +} + +func bindObject(t types.Type, object *Object, imports *Imports) BindErrors { + var errs BindErrors + for i := range object.Fields { + field := &object.Fields[i] + + // first try binding to a method + methodErr := bindMethod(imports, t, field) + if methodErr == nil { + continue + } + + // otherwise try binding to a var + varErr := bindVar(imports, t, field) + + if varErr != nil { + errs = append(errs, BindError{ + object: object, + typ: t, + field: field, + varErr: varErr, + methodErr: methodErr, + }) + } + } + return errs +} + +func bindMethod(imports *Imports, t types.Type, field *Field) error { namedType, ok := t.(*types.Named) if !ok { - return errors.Errorf("expected %s to be a named struct, instead found %s", object.FullName(), t.String()) + return fmt.Errorf("not a named type") + } + + method := findMethod(namedType, field.GQLName) + if method == nil { + return fmt.Errorf("no method named %s", field.GQLName) + } + sig := method.Type().(*types.Signature) + + if sig.Results().Len() == 1 { + field.NoErr = true + } else if sig.Results().Len() != 2 { + return fmt.Errorf("method has wrong number of args") + } + newArgs, err := matchArgs(field, sig.Params()) + if err != nil { + return err } + result := sig.Results().At(0) + if err := validateTypeBinding(imports, field, result.Type()); err != nil { + return errors.Wrap(err, "method has wrong return type") + } + + // success, args and return type match. Bind to method + field.GoMethodName = "obj." + method.Name() + field.Args = newArgs + return nil +} + +func bindVar(imports *Imports, t types.Type, field *Field) error { underlying, ok := t.Underlying().(*types.Struct) if !ok { - return errors.Errorf("expected %s to be a named struct, instead found %s", object.FullName(), t.String()) + return fmt.Errorf("not a struct") } - for i := range object.Fields { - field := &object.Fields[i] - if method := findMethod(namedType, field.GQLName); method != nil { - sig := method.Type().(*types.Signature) - field.GoMethodName = "obj." + method.Name() - field.Type.Modifiers = modifiersFromGoType(sig.Results().At(0).Type()) - - // check arg order matches code, not gql - var newArgs []FieldArgument - l2: - for j := 0; j < sig.Params().Len(); j++ { - param := sig.Params().At(j) - for _, oldArg := range field.Args { - if strings.EqualFold(oldArg.GQLName, param.Name()) { - oldArg.Type.Modifiers = modifiersFromGoType(param.Type()) - newArgs = append(newArgs, oldArg) - continue l2 - } - } - return errors.Errorf("cannot match argument " + param.Name() + " to any argument in " + t.String()) - } - field.Args = newArgs + structField := findField(underlying, field.GQLName) + if structField == nil { + return fmt.Errorf("no field named %s", field.GQLName) + } + + if err := validateTypeBinding(imports, field, structField.Type()); err != nil { + return errors.Wrap(err, "field has wrong type") + } - if sig.Results().Len() == 1 { - field.NoErr = true - } else if sig.Results().Len() != 2 { - return errors.Errorf("weird number of results on %s. expected either (result), or (result, error)\n", method.Name()) + // success, bind to var + field.GoVarName = structField.Name() + return nil +} + +func matchArgs(field *Field, params *types.Tuple) ([]FieldArgument, error) { + var newArgs []FieldArgument + +nextArg: + for j := 0; j < params.Len(); j++ { + param := params.At(j) + for _, oldArg := range field.Args { + if strings.EqualFold(oldArg.GQLName, param.Name()) { + oldArg.Type.Modifiers = modifiersFromGoType(param.Type()) + newArgs = append(newArgs, oldArg) + continue nextArg } - continue } - if structField := findField(underlying, field.GQLName); structField != nil { - prevModifiers := field.Type.Modifiers - field.Type.Modifiers = modifiersFromGoType(structField.Type()) - field.GoVarName = structField.Name() + // no matching arg found, abort + return nil, fmt.Errorf("arg %s not found on method", param.Name()) + } + return newArgs, nil +} - switch normalizeVendor(field.Type.FullSignature()) { - case normalizeVendor(structField.Type().String()): - // everything is fine +func validateTypeBinding(imports *Imports, field *Field, goType types.Type) error { + gqlType := normalizeVendor(field.Type.FullSignature()) + goTypeStr := normalizeVendor(goType.String()) - case normalizeVendor(structField.Type().Underlying().String()): - pkg, typ := pkgAndType(structField.Type().String()) - imp := imports.findByPath(pkg) - field.CastType = &Ref{GoType: typ, Import: imp} + if goTypeStr == gqlType || "*"+goTypeStr == gqlType || goTypeStr == "*"+gqlType { + field.Type.Modifiers = modifiersFromGoType(goType) + return nil + } - default: - // type mismatch, require custom resolver for field - field.GoVarName = "" - field.Type.Modifiers = prevModifiers - } - continue - } + // deal with type aliases + underlyingStr := normalizeVendor(goType.Underlying().String()) + if underlyingStr == gqlType || "*"+underlyingStr == gqlType || underlyingStr == "*"+gqlType { + field.Type.Modifiers = modifiersFromGoType(goType) + pkg, typ := pkgAndType(goType.String()) + imp := imports.findByPath(pkg) + field.CastType = &Ref{GoType: typ, Import: imp} + return nil } - return nil + + return fmt.Errorf("%s is not compatible with %s", gqlType, goTypeStr) } func modifiersFromGoType(t types.Type) []string { diff --git a/example/chat/generated.go b/example/chat/generated.go index ea16d4cd235..3b903cece08 100644 --- a/example/chat/generated.go +++ b/example/chat/generated.go @@ -595,10 +595,7 @@ func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___InputValue(ctx, field.Selections, res[idx1]) + return ec.___InputValue(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -755,10 +752,7 @@ func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.Col rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___InputValue(ctx, field.Selections, res[idx1]) + return ec.___InputValue(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -772,10 +766,7 @@ func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.Col rctx.PushField(field.Alias) defer rctx.Pop() res := obj.Type() - if res == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res) + return ec.___Type(ctx, field.Selections, &res) } func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) graphql.Marshaler { @@ -865,10 +856,7 @@ func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphq rctx.PushField(field.Alias) defer rctx.Pop() res := obj.Type() - if res == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res) + return ec.___Type(ctx, field.Selections, &res) } func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) graphql.Marshaler { @@ -930,10 +918,7 @@ func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.C rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res[idx1]) + return ec.___Type(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -947,10 +932,7 @@ func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graph rctx.PushField(field.Alias) defer rctx.Pop() res := obj.QueryType() - if res == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res) + return ec.___Type(ctx, field.Selections, &res) } func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) graphql.Marshaler { @@ -995,10 +977,7 @@ func (ec *executionContext) ___Schema_directives(ctx context.Context, field grap rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Directive(ctx, field.Selections, res[idx1]) + return ec.___Directive(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1107,10 +1086,7 @@ func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.Co rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Field(ctx, field.Selections, res[idx1]) + return ec.___Field(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1130,10 +1106,7 @@ func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphq rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res[idx1]) + return ec.___Type(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1153,10 +1126,7 @@ func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field gra rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res[idx1]) + return ec.___Type(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1187,10 +1157,7 @@ func (ec *executionContext) ___Type_enumValues(ctx context.Context, field graphq rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___EnumValue(ctx, field.Selections, res[idx1]) + return ec.___EnumValue(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1210,10 +1177,7 @@ func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graph rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___InputValue(ctx, field.Selections, res[idx1]) + return ec.___InputValue(ctx, field.Selections, &res[idx1]) }()) } return arr1 diff --git a/example/dataloader/generated.go b/example/dataloader/generated.go index 998b51d77b4..0893a01544d 100644 --- a/example/dataloader/generated.go +++ b/example/dataloader/generated.go @@ -705,10 +705,7 @@ func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___InputValue(ctx, field.Selections, res[idx1]) + return ec.___InputValue(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -865,10 +862,7 @@ func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.Col rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___InputValue(ctx, field.Selections, res[idx1]) + return ec.___InputValue(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -882,10 +876,7 @@ func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.Col rctx.PushField(field.Alias) defer rctx.Pop() res := obj.Type() - if res == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res) + return ec.___Type(ctx, field.Selections, &res) } func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) graphql.Marshaler { @@ -975,10 +966,7 @@ func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphq rctx.PushField(field.Alias) defer rctx.Pop() res := obj.Type() - if res == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res) + return ec.___Type(ctx, field.Selections, &res) } func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) graphql.Marshaler { @@ -1040,10 +1028,7 @@ func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.C rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res[idx1]) + return ec.___Type(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1057,10 +1042,7 @@ func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graph rctx.PushField(field.Alias) defer rctx.Pop() res := obj.QueryType() - if res == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res) + return ec.___Type(ctx, field.Selections, &res) } func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) graphql.Marshaler { @@ -1105,10 +1087,7 @@ func (ec *executionContext) ___Schema_directives(ctx context.Context, field grap rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Directive(ctx, field.Selections, res[idx1]) + return ec.___Directive(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1217,10 +1196,7 @@ func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.Co rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Field(ctx, field.Selections, res[idx1]) + return ec.___Field(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1240,10 +1216,7 @@ func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphq rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res[idx1]) + return ec.___Type(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1263,10 +1236,7 @@ func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field gra rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res[idx1]) + return ec.___Type(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1297,10 +1267,7 @@ func (ec *executionContext) ___Type_enumValues(ctx context.Context, field graphq rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___EnumValue(ctx, field.Selections, res[idx1]) + return ec.___EnumValue(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1320,10 +1287,7 @@ func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graph rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___InputValue(ctx, field.Selections, res[idx1]) + return ec.___InputValue(ctx, field.Selections, &res[idx1]) }()) } return arr1 diff --git a/example/scalars/generated.go b/example/scalars/generated.go index dc588ec34a0..8d099b7c7eb 100644 --- a/example/scalars/generated.go +++ b/example/scalars/generated.go @@ -581,10 +581,7 @@ func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___InputValue(ctx, field.Selections, res[idx1]) + return ec.___InputValue(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -741,10 +738,7 @@ func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.Col rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___InputValue(ctx, field.Selections, res[idx1]) + return ec.___InputValue(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -758,10 +752,7 @@ func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.Col rctx.PushField(field.Alias) defer rctx.Pop() res := obj.Type() - if res == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res) + return ec.___Type(ctx, field.Selections, &res) } func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) graphql.Marshaler { @@ -851,10 +842,7 @@ func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphq rctx.PushField(field.Alias) defer rctx.Pop() res := obj.Type() - if res == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res) + return ec.___Type(ctx, field.Selections, &res) } func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) graphql.Marshaler { @@ -916,10 +904,7 @@ func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.C rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res[idx1]) + return ec.___Type(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -933,10 +918,7 @@ func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graph rctx.PushField(field.Alias) defer rctx.Pop() res := obj.QueryType() - if res == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res) + return ec.___Type(ctx, field.Selections, &res) } func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) graphql.Marshaler { @@ -981,10 +963,7 @@ func (ec *executionContext) ___Schema_directives(ctx context.Context, field grap rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Directive(ctx, field.Selections, res[idx1]) + return ec.___Directive(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1093,10 +1072,7 @@ func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.Co rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Field(ctx, field.Selections, res[idx1]) + return ec.___Field(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1116,10 +1092,7 @@ func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphq rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res[idx1]) + return ec.___Type(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1139,10 +1112,7 @@ func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field gra rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res[idx1]) + return ec.___Type(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1173,10 +1143,7 @@ func (ec *executionContext) ___Type_enumValues(ctx context.Context, field graphq rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___EnumValue(ctx, field.Selections, res[idx1]) + return ec.___EnumValue(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1196,10 +1163,7 @@ func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graph rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___InputValue(ctx, field.Selections, res[idx1]) + return ec.___InputValue(ctx, field.Selections, &res[idx1]) }()) } return arr1 diff --git a/example/selection/generated.go b/example/selection/generated.go index 83990834c66..71d5e8de99c 100644 --- a/example/selection/generated.go +++ b/example/selection/generated.go @@ -460,10 +460,7 @@ func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___InputValue(ctx, field.Selections, res[idx1]) + return ec.___InputValue(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -620,10 +617,7 @@ func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.Col rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___InputValue(ctx, field.Selections, res[idx1]) + return ec.___InputValue(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -637,10 +631,7 @@ func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.Col rctx.PushField(field.Alias) defer rctx.Pop() res := obj.Type() - if res == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res) + return ec.___Type(ctx, field.Selections, &res) } func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) graphql.Marshaler { @@ -730,10 +721,7 @@ func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphq rctx.PushField(field.Alias) defer rctx.Pop() res := obj.Type() - if res == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res) + return ec.___Type(ctx, field.Selections, &res) } func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) graphql.Marshaler { @@ -795,10 +783,7 @@ func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.C rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res[idx1]) + return ec.___Type(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -812,10 +797,7 @@ func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graph rctx.PushField(field.Alias) defer rctx.Pop() res := obj.QueryType() - if res == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res) + return ec.___Type(ctx, field.Selections, &res) } func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) graphql.Marshaler { @@ -860,10 +842,7 @@ func (ec *executionContext) ___Schema_directives(ctx context.Context, field grap rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Directive(ctx, field.Selections, res[idx1]) + return ec.___Directive(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -972,10 +951,7 @@ func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.Co rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Field(ctx, field.Selections, res[idx1]) + return ec.___Field(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -995,10 +971,7 @@ func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphq rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res[idx1]) + return ec.___Type(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1018,10 +991,7 @@ func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field gra rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res[idx1]) + return ec.___Type(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1052,10 +1022,7 @@ func (ec *executionContext) ___Type_enumValues(ctx context.Context, field graphq rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___EnumValue(ctx, field.Selections, res[idx1]) + return ec.___EnumValue(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1075,10 +1042,7 @@ func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graph rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___InputValue(ctx, field.Selections, res[idx1]) + return ec.___InputValue(ctx, field.Selections, &res[idx1]) }()) } return arr1 diff --git a/example/starwars/generated.go b/example/starwars/generated.go index 928e4b22d25..387dc217a01 100644 --- a/example/starwars/generated.go +++ b/example/starwars/generated.go @@ -1660,10 +1660,7 @@ func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___InputValue(ctx, field.Selections, res[idx1]) + return ec.___InputValue(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1820,10 +1817,7 @@ func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.Col rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___InputValue(ctx, field.Selections, res[idx1]) + return ec.___InputValue(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1837,10 +1831,7 @@ func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.Col rctx.PushField(field.Alias) defer rctx.Pop() res := obj.Type() - if res == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res) + return ec.___Type(ctx, field.Selections, &res) } func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) graphql.Marshaler { @@ -1930,10 +1921,7 @@ func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphq rctx.PushField(field.Alias) defer rctx.Pop() res := obj.Type() - if res == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res) + return ec.___Type(ctx, field.Selections, &res) } func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) graphql.Marshaler { @@ -1995,10 +1983,7 @@ func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.C rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res[idx1]) + return ec.___Type(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -2012,10 +1997,7 @@ func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graph rctx.PushField(field.Alias) defer rctx.Pop() res := obj.QueryType() - if res == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res) + return ec.___Type(ctx, field.Selections, &res) } func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) graphql.Marshaler { @@ -2060,10 +2042,7 @@ func (ec *executionContext) ___Schema_directives(ctx context.Context, field grap rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Directive(ctx, field.Selections, res[idx1]) + return ec.___Directive(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -2172,10 +2151,7 @@ func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.Co rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Field(ctx, field.Selections, res[idx1]) + return ec.___Field(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -2195,10 +2171,7 @@ func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphq rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res[idx1]) + return ec.___Type(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -2218,10 +2191,7 @@ func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field gra rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res[idx1]) + return ec.___Type(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -2252,10 +2222,7 @@ func (ec *executionContext) ___Type_enumValues(ctx context.Context, field graphq rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___EnumValue(ctx, field.Selections, res[idx1]) + return ec.___EnumValue(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -2275,10 +2242,7 @@ func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graph rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___InputValue(ctx, field.Selections, res[idx1]) + return ec.___InputValue(ctx, field.Selections, &res[idx1]) }()) } return arr1 diff --git a/example/todo/generated.go b/example/todo/generated.go index edcc028460d..5128534d4d2 100644 --- a/example/todo/generated.go +++ b/example/todo/generated.go @@ -563,10 +563,7 @@ func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___InputValue(ctx, field.Selections, res[idx1]) + return ec.___InputValue(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -723,10 +720,7 @@ func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.Col rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___InputValue(ctx, field.Selections, res[idx1]) + return ec.___InputValue(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -740,10 +734,7 @@ func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.Col rctx.PushField(field.Alias) defer rctx.Pop() res := obj.Type() - if res == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res) + return ec.___Type(ctx, field.Selections, &res) } func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) graphql.Marshaler { @@ -833,10 +824,7 @@ func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphq rctx.PushField(field.Alias) defer rctx.Pop() res := obj.Type() - if res == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res) + return ec.___Type(ctx, field.Selections, &res) } func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) graphql.Marshaler { @@ -898,10 +886,7 @@ func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.C rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res[idx1]) + return ec.___Type(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -915,10 +900,7 @@ func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graph rctx.PushField(field.Alias) defer rctx.Pop() res := obj.QueryType() - if res == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res) + return ec.___Type(ctx, field.Selections, &res) } func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) graphql.Marshaler { @@ -963,10 +945,7 @@ func (ec *executionContext) ___Schema_directives(ctx context.Context, field grap rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Directive(ctx, field.Selections, res[idx1]) + return ec.___Directive(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1075,10 +1054,7 @@ func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.Co rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Field(ctx, field.Selections, res[idx1]) + return ec.___Field(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1098,10 +1074,7 @@ func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphq rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res[idx1]) + return ec.___Type(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1121,10 +1094,7 @@ func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field gra rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res[idx1]) + return ec.___Type(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1155,10 +1125,7 @@ func (ec *executionContext) ___Type_enumValues(ctx context.Context, field graphq rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___EnumValue(ctx, field.Selections, res[idx1]) + return ec.___EnumValue(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1178,10 +1145,7 @@ func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graph rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___InputValue(ctx, field.Selections, res[idx1]) + return ec.___InputValue(ctx, field.Selections, &res[idx1]) }()) } return arr1 diff --git a/main.go b/main.go index 5884aaf3a6b..5b2843886f3 100644 --- a/main.go +++ b/main.go @@ -4,6 +4,7 @@ import ( "flag" "fmt" "io/ioutil" + "log" "os" "github.com/vektah/gqlgen/codegen" @@ -18,6 +19,7 @@ var typemap = flag.String("typemap", "", "a json map going from graphql to golan var packageName = flag.String("package", "", "the package name") var modelPackageName = flag.String("modelpackage", "", "the package name to use for models") var help = flag.Bool("h", false, "this usage text") +var verbose = flag.Bool("v", false, "show logs") func main() { flag.Usage = func() { @@ -31,6 +33,11 @@ func main() { flag.Usage() os.Exit(1) } + if *verbose { + log.SetFlags(0) + } else { + log.SetOutput(ioutil.Discard) + } var config *codegen.Config var err error diff --git a/neelance/introspection/introspection.go b/neelance/introspection/introspection.go index 0bf8cbbfa9f..5e354c9ac25 100644 --- a/neelance/introspection/introspection.go +++ b/neelance/introspection/introspection.go @@ -16,40 +16,40 @@ func WrapSchema(schema *schema.Schema) *Schema { return &Schema{schema} } -func (r *Schema) Types() []*Type { +func (r *Schema) Types() []Type { var names []string for name := range r.schema.Types { names = append(names, name) } sort.Strings(names) - l := make([]*Type, len(names)) + l := make([]Type, len(names)) for i, name := range names { - l[i] = &Type{r.schema.Types[name]} + l[i] = Type{r.schema.Types[name]} } return l } -func (r *Schema) Directives() []*Directive { +func (r *Schema) Directives() []Directive { var names []string for name := range r.schema.Directives { names = append(names, name) } sort.Strings(names) - l := make([]*Directive, len(names)) + l := make([]Directive, len(names)) for i, name := range names { - l[i] = &Directive{r.schema.Directives[name]} + l[i] = Directive{r.schema.Directives[name]} } return l } -func (r *Schema) QueryType() *Type { +func (r *Schema) QueryType() Type { t, ok := r.schema.EntryPoints["query"] if !ok { - return nil + return Type{} } - return &Type{t} + return Type{t} } func (r *Schema) MutationType() *Type { @@ -100,7 +100,7 @@ func (r *Type) Description() *string { return nil } -func (r *Type) Fields(includeDeprecated bool) []*Field { +func (r *Type) Fields(includeDeprecated bool) []Field { var fields schema.FieldList switch t := r.typ.(type) { case *schema.Object: @@ -111,29 +111,29 @@ func (r *Type) Fields(includeDeprecated bool) []*Field { return nil } - var l []*Field + var l []Field for _, f := range fields { if d := f.Directives.Get("deprecated"); d == nil || includeDeprecated { - l = append(l, &Field{f}) + l = append(l, Field{f}) } } return l } -func (r *Type) Interfaces() []*Type { +func (r *Type) Interfaces() []Type { t, ok := r.typ.(*schema.Object) if !ok { return nil } - l := make([]*Type, len(t.Interfaces)) + l := make([]Type, len(t.Interfaces)) for i, intf := range t.Interfaces { - l[i] = &Type{intf} + l[i] = Type{intf} } return l } -func (r *Type) PossibleTypes() []*Type { +func (r *Type) PossibleTypes() []Type { var possibleTypes []*schema.Object switch t := r.typ.(type) { case *schema.Interface: @@ -144,37 +144,37 @@ func (r *Type) PossibleTypes() []*Type { return nil } - l := make([]*Type, len(possibleTypes)) + l := make([]Type, len(possibleTypes)) for i, intf := range possibleTypes { - l[i] = &Type{intf} + l[i] = Type{intf} } return l } -func (r *Type) EnumValues(includeDeprecated bool) []*EnumValue { +func (r *Type) EnumValues(includeDeprecated bool) []EnumValue { t, ok := r.typ.(*schema.Enum) if !ok { return nil } - var l []*EnumValue + var l []EnumValue for _, v := range t.Values { if d := v.Directives.Get("deprecated"); d == nil || includeDeprecated { - l = append(l, &EnumValue{v}) + l = append(l, EnumValue{v}) } } return l } -func (r *Type) InputFields() []*InputValue { +func (r *Type) InputFields() []InputValue { t, ok := r.typ.(*schema.InputObject) if !ok { return nil } - l := make([]*InputValue, len(t.Values)) + l := make([]InputValue, len(t.Values)) for i, v := range t.Values { - l[i] = &InputValue{v} + l[i] = InputValue{v} } return l } @@ -205,16 +205,16 @@ func (r *Field) Description() *string { return &r.field.Desc } -func (r *Field) Args() []*InputValue { - l := make([]*InputValue, len(r.field.Args)) +func (r *Field) Args() []InputValue { + l := make([]InputValue, len(r.field.Args)) for i, v := range r.field.Args { - l[i] = &InputValue{v} + l[i] = InputValue{v} } return l } -func (r *Field) Type() *Type { - return &Type{r.field.Type} +func (r *Field) Type() Type { + return Type{r.field.Type} } func (r *Field) IsDeprecated() bool { @@ -245,8 +245,8 @@ func (r *InputValue) Description() *string { return &r.value.Desc } -func (r *InputValue) Type() *Type { - return &Type{r.value.Type} +func (r *InputValue) Type() Type { + return Type{r.value.Type} } func (r *InputValue) DefaultValue() *string { @@ -304,10 +304,10 @@ func (r *Directive) Locations() []string { return r.directive.Locs } -func (r *Directive) Args() []*InputValue { - l := make([]*InputValue, len(r.directive.Args)) +func (r *Directive) Args() []InputValue { + l := make([]InputValue, len(r.directive.Args)) for i, v := range r.directive.Args { - l[i] = &InputValue{v} + l[i] = InputValue{v} } return l } diff --git a/test/generated.go b/test/generated.go index fa4a5ce878b..b2db94550bc 100644 --- a/test/generated.go +++ b/test/generated.go @@ -28,6 +28,7 @@ func NewExecutableSchema(resolvers ResolverRoot) graphql.ExecutableSchema { type Resolvers interface { Element_child(ctx context.Context, obj *models.Element) (models.Element, error) Element_error(ctx context.Context, obj *models.Element) (bool, error) + Element_mismatched(ctx context.Context, obj *models.Element) ([]bool, error) Query_path(ctx context.Context) ([]*models.Element, error) Query_date(ctx context.Context, filter models.DateFilter) (bool, error) Query_viewer(ctx context.Context) (*models.Viewer, error) @@ -44,6 +45,7 @@ type ResolverRoot interface { type ElementResolver interface { Child(ctx context.Context, obj *models.Element) (models.Element, error) Error(ctx context.Context, obj *models.Element) (bool, error) + Mismatched(ctx context.Context, obj *models.Element) ([]bool, error) } type QueryResolver interface { Path(ctx context.Context) ([]*models.Element, error) @@ -67,6 +69,10 @@ func (s shortMapper) Element_error(ctx context.Context, obj *models.Element) (bo return s.r.Element().Error(ctx, obj) } +func (s shortMapper) Element_mismatched(ctx context.Context, obj *models.Element) ([]bool, error) { + return s.r.Element().Mismatched(ctx, obj) +} + func (s shortMapper) Query_path(ctx context.Context) ([]*models.Element, error) { return s.r.Query().Path(ctx) } @@ -142,6 +148,8 @@ func (ec *executionContext) _Element(ctx context.Context, sel []query.Selection, out.Values[i] = ec._Element_child(ctx, field, obj) case "error": out.Values[i] = ec._Element_error(ctx, field, obj) + case "mismatched": + out.Values[i] = ec._Element_mismatched(ctx, field, obj) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -210,6 +218,45 @@ func (ec *executionContext) _Element_error(ctx context.Context, field graphql.Co }) } +func (ec *executionContext) _Element_mismatched(ctx context.Context, field graphql.CollectedField, obj *models.Element) graphql.Marshaler { + ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{ + Object: "Element", + Args: nil, + Field: field, + }) + return graphql.Defer(func() (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + userErr := ec.Recover(ctx, r) + ec.Error(ctx, userErr) + ret = graphql.Null + } + }() + + resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return ec.resolvers.Element_mismatched(ctx, obj) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]bool) + arr1 := graphql.Array{} + for idx1 := range res { + arr1 = append(arr1, func() graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.PushIndex(idx1) + defer rctx.Pop() + return graphql.MarshalBoolean(res[idx1]) + }()) + } + return arr1 + }) +} + var queryImplementors = []string{"Query"} // nolint: gocyclo, errcheck, gas, goconst @@ -632,10 +679,7 @@ func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___InputValue(ctx, field.Selections, res[idx1]) + return ec.___InputValue(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -792,10 +836,7 @@ func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.Col rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___InputValue(ctx, field.Selections, res[idx1]) + return ec.___InputValue(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -809,10 +850,7 @@ func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.Col rctx.PushField(field.Alias) defer rctx.Pop() res := obj.Type() - if res == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res) + return ec.___Type(ctx, field.Selections, &res) } func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) graphql.Marshaler { @@ -902,10 +940,7 @@ func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphq rctx.PushField(field.Alias) defer rctx.Pop() res := obj.Type() - if res == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res) + return ec.___Type(ctx, field.Selections, &res) } func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) graphql.Marshaler { @@ -967,10 +1002,7 @@ func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.C rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res[idx1]) + return ec.___Type(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -984,10 +1016,7 @@ func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graph rctx.PushField(field.Alias) defer rctx.Pop() res := obj.QueryType() - if res == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res) + return ec.___Type(ctx, field.Selections, &res) } func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) graphql.Marshaler { @@ -1032,10 +1061,7 @@ func (ec *executionContext) ___Schema_directives(ctx context.Context, field grap rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Directive(ctx, field.Selections, res[idx1]) + return ec.___Directive(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1144,10 +1170,7 @@ func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.Co rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Field(ctx, field.Selections, res[idx1]) + return ec.___Field(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1167,10 +1190,7 @@ func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphq rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res[idx1]) + return ec.___Type(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1190,10 +1210,7 @@ func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field gra rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___Type(ctx, field.Selections, res[idx1]) + return ec.___Type(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1224,10 +1241,7 @@ func (ec *executionContext) ___Type_enumValues(ctx context.Context, field graphq rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___EnumValue(ctx, field.Selections, res[idx1]) + return ec.___EnumValue(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1247,10 +1261,7 @@ func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graph rctx := graphql.GetResolverContext(ctx) rctx.PushIndex(idx1) defer rctx.Pop() - if res[idx1] == nil { - return graphql.Null - } - return ec.___InputValue(ctx, field.Selections, res[idx1]) + return ec.___InputValue(ctx, field.Selections, &res[idx1]) }()) } return arr1 @@ -1332,6 +1343,7 @@ func (ec *executionContext) introspectType(name string) *introspection.Type { var parsedSchema = schema.MustParse(`type Element { child: Element! error: Boolean! + mismatched: [Boolean!] } enum DATE_FILTER_OP { @@ -1350,8 +1362,8 @@ input DateFilter { } type User { - name: String - likes: [String] + name: String! + likes: [String!]! } type Viewer { diff --git a/test/models-go/element.go b/test/models-go/element.go index 91e9767fa79..de64deb01bb 100644 --- a/test/models-go/element.go +++ b/test/models-go/element.go @@ -3,3 +3,7 @@ package models type Element struct { ID int } + +func (e *Element) Mismatched() []Element { + return []Element{*e} +} diff --git a/test/resolvers_test.go b/test/resolvers_test.go index 1716ab1474e..7f4c04bf615 100644 --- a/test/resolvers_test.go +++ b/test/resolvers_test.go @@ -142,6 +142,10 @@ func (r *testResolvers) Element_error(ctx context.Context, obj *models.Element) return false, r.err } +func (r *testResolvers) Element_mismatched(ctx context.Context, obj *models.Element) ([]bool, error) { + return []bool{true}, nil +} + func (r *testResolvers) User_likes(ctx context.Context, obj *remote_api.User) ([]string, error) { return obj.Likes, nil } diff --git a/test/schema.graphql b/test/schema.graphql index 1b8245236d2..c745a7e7c7b 100644 --- a/test/schema.graphql +++ b/test/schema.graphql @@ -1,6 +1,7 @@ type Element { child: Element! error: Boolean! + mismatched: [Boolean!] } enum DATE_FILTER_OP { @@ -19,8 +20,8 @@ input DateFilter { } type User { - name: String - likes: [String] + name: String! + likes: [String!]! } type Viewer {