diff --git a/codegen/testserver/generated.go b/codegen/testserver/generated.go index 7fd6c759ef..d3b4980ff6 100644 --- a/codegen/testserver/generated.go +++ b/codegen/testserver/generated.go @@ -96,6 +96,10 @@ type ComplexityRoot struct { ID func(childComplexity int) int } + CheckIssue896 struct { + ID func(childComplexity int) int + } + Circle struct { Area func(childComplexity int) int Radius func(childComplexity int) int @@ -244,6 +248,7 @@ type ComplexityRoot struct { Fallback func(childComplexity int, arg FallbackToStringEncoding) int InputSlice func(childComplexity int, arg []string) int InvalidIdentifier func(childComplexity int) int + Issue896a func(childComplexity int) int MapInput func(childComplexity int, input map[string]interface{}) int MapNestedStringInterface func(childComplexity int, in *NestedMapInput) int MapStringInterface func(childComplexity int, in map[string]interface{}) int @@ -288,6 +293,7 @@ type ComplexityRoot struct { DirectiveNullableArg func(childComplexity int, arg *int, arg2 *int, arg3 *string) int DirectiveUnimplemented func(childComplexity int) int InitPayload func(childComplexity int) int + Issue896b func(childComplexity int) int Updated func(childComplexity int) int } @@ -386,6 +392,7 @@ type QueryResolver interface { EmbeddedCase3(ctx context.Context) (*EmbeddedCase3, error) Shapes(ctx context.Context) ([]Shape, error) NoShape(ctx context.Context) (Shape, error) + Issue896a(ctx context.Context) ([]*CheckIssue896, error) MapStringInterface(ctx context.Context, in map[string]interface{}) (map[string]interface{}, error) MapNestedStringInterface(ctx context.Context, in *NestedMapInput) (map[string]interface{}, error) ErrorBubble(ctx context.Context) (*Error, error) @@ -410,6 +417,7 @@ type SubscriptionResolver interface { DirectiveNullableArg(ctx context.Context, arg *int, arg2 *int, arg3 *string) (<-chan *string, error) DirectiveDouble(ctx context.Context) (<-chan *string, error) DirectiveUnimplemented(ctx context.Context) (<-chan *string, error) + Issue896b(ctx context.Context) (<-chan []*CheckIssue896, error) } type UserResolver interface { Friends(ctx context.Context, obj *User) ([]*User, error) @@ -493,6 +501,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.B.ID(childComplexity), true + case "CheckIssue896.id": + if e.complexity.CheckIssue896.ID == nil { + break + } + + return e.complexity.CheckIssue896.ID(childComplexity), true + case "Circle.area": if e.complexity.Circle.Area == nil { break @@ -1031,6 +1046,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.InvalidIdentifier(childComplexity), true + case "Query.issue896a": + if e.complexity.Query.Issue896a == nil { + break + } + + return e.complexity.Query.Issue896a(childComplexity), true + case "Query.mapInput": if e.complexity.Query.MapInput == nil { break @@ -1321,6 +1343,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Subscription.InitPayload(childComplexity), true + case "Subscription.issue896b": + if e.complexity.Subscription.Issue896b == nil { + break + } + + return e.complexity.Subscription.Issue896b(childComplexity), true + case "Subscription.updated": if e.complexity.Subscription.Updated == nil { break @@ -1617,6 +1646,25 @@ type Rectangle implements Shape { union ShapeUnion @goModel(model:"testserver.ShapeUnion") = Circle | Rectangle directive @makeNil on FIELD_DEFINITION +`}, + &ast.Source{Name: "issue896.graphql", Input: `# This example should build stable output. If the file content starts +# alternating nondeterministically between two outputs, then see +# https://github.com/99designs/gqlgen/issues/896. + +extend schema { + query: Query + subscription: Subscription +} + +type CheckIssue896 {id: Int} + +extend type Query { + issue896a: [CheckIssue896!] # Note the "!" or lack thereof. +} + +extend type Subscription { + issue896b: [CheckIssue896] # Note the "!" or lack thereof. +} `}, &ast.Source{Name: "loops.graphql", Input: `type LoopA { b: LoopB! @@ -3108,6 +3156,37 @@ func (ec *executionContext) _B_id(ctx context.Context, field graphql.CollectedFi return ec.marshalNID2string(ctx, field.Selections, res) } +func (ec *executionContext) _CheckIssue896_id(ctx context.Context, field graphql.CollectedField, obj *CheckIssue896) (ret graphql.Marshaler) { + ctx = ec.Tracer.StartFieldExecution(ctx, field) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + ec.Tracer.EndFieldExecution(ctx) + }() + rctx := &graphql.ResolverContext{ + Object: "CheckIssue896", + Field: field, + Args: nil, + IsMethod: false, + } + ctx = graphql.WithResolverContext(ctx, rctx) + ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*int) + rctx.Result = res + ctx = ec.Tracer.StartFieldChildExecution(ctx) + return ec.marshalOInt2ᚖint(ctx, field.Selections, res) +} + func (ec *executionContext) _Circle_radius(ctx context.Context, field graphql.CollectedField, obj *Circle) (ret graphql.Marshaler) { ctx = ec.Tracer.StartFieldExecution(ctx, field) defer func() { @@ -5928,6 +6007,37 @@ func (ec *executionContext) _Query_noShape(ctx context.Context, field graphql.Co return ec.marshalOShape2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐShape(ctx, field.Selections, res) } +func (ec *executionContext) _Query_issue896a(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + ctx = ec.Tracer.StartFieldExecution(ctx, field) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + ec.Tracer.EndFieldExecution(ctx) + }() + rctx := &graphql.ResolverContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + } + ctx = graphql.WithResolverContext(ctx, rctx) + ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Issue896a(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*CheckIssue896) + rctx.Result = res + ctx = ec.Tracer.StartFieldChildExecution(ctx) + return ec.marshalOCheckIssue8962ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐCheckIssue896ᚄ(ctx, field.Selections, res) +} + func (ec *executionContext) _Query_mapStringInterface(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { ctx = ec.Tracer.StartFieldExecution(ctx, field) defer func() { @@ -7074,6 +7184,46 @@ func (ec *executionContext) _Subscription_directiveUnimplemented(ctx context.Con } } +func (ec *executionContext) _Subscription_issue896b(ctx context.Context, field graphql.CollectedField) (ret func() graphql.Marshaler) { + ctx = ec.Tracer.StartFieldExecution(ctx, field) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + ec.Tracer.EndFieldExecution(ctx) + }() + rctx := &graphql.ResolverContext{ + Object: "Subscription", + Field: field, + Args: nil, + IsMethod: true, + } + ctx = graphql.WithResolverContext(ctx, rctx) + ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Subscription().Issue896b(rctx) + }) + + if resTmp == nil { + return nil + } + return func() graphql.Marshaler { + res, ok := <-resTmp.(<-chan []*CheckIssue896) + if !ok { + return nil + } + return graphql.WriterFunc(func(w io.Writer) { + w.Write([]byte{'{'}) + graphql.MarshalString(field.Alias).MarshalGQL(w) + w.Write([]byte{':'}) + ec.marshalOCheckIssue8962ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐCheckIssue896(ctx, field.Selections, res).MarshalGQL(w) + w.Write([]byte{'}'}) + }) + } +} + func (ec *executionContext) _User_id(ctx context.Context, field graphql.CollectedField, obj *User) (ret graphql.Marshaler) { ctx = ec.Tracer.StartFieldExecution(ctx, field) defer func() { @@ -9191,6 +9341,30 @@ func (ec *executionContext) _B(ctx context.Context, sel ast.SelectionSet, obj *B return out } +var checkIssue896Implementors = []string{"CheckIssue896"} + +func (ec *executionContext) _CheckIssue896(ctx context.Context, sel ast.SelectionSet, obj *CheckIssue896) graphql.Marshaler { + fields := graphql.CollectFields(ec.RequestContext, sel, checkIssue896Implementors) + + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("CheckIssue896") + case "id": + out.Values[i] = ec._CheckIssue896_id(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + var circleImplementors = []string{"Circle", "Shape", "ShapeUnion"} func (ec *executionContext) _Circle(ctx context.Context, sel ast.SelectionSet, obj *Circle) graphql.Marshaler { @@ -10459,6 +10633,17 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr res = ec._Query_noShape(ctx, field) return res }) + case "issue896a": + field := field + out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_issue896a(ctx, field) + return res + }) case "mapStringInterface": field := field out.Concurrently(i, func() (res graphql.Marshaler) { @@ -10763,6 +10948,8 @@ func (ec *executionContext) _Subscription(ctx context.Context, sel ast.Selection return ec._Subscription_directiveDouble(ctx, fields[0]) case "directiveUnimplemented": return ec._Subscription_directiveUnimplemented(ctx, fields[0]) + case "issue896b": + return ec._Subscription_issue896b(ctx, fields[0]) default: panic("unknown field " + strconv.Quote(fields[0].Name)) } @@ -11266,6 +11453,20 @@ func (ec *executionContext) marshalNBytes2ᚕbyte(ctx context.Context, sel ast.S return res } +func (ec *executionContext) marshalNCheckIssue8962githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐCheckIssue896(ctx context.Context, sel ast.SelectionSet, v CheckIssue896) graphql.Marshaler { + return ec._CheckIssue896(ctx, sel, &v) +} + +func (ec *executionContext) marshalNCheckIssue8962ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐCheckIssue896(ctx context.Context, sel ast.SelectionSet, v *CheckIssue896) graphql.Marshaler { + if v == nil { + if !ec.HasError(graphql.GetResolverContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._CheckIssue896(ctx, sel, v) +} + func (ec *executionContext) unmarshalNDefaultScalarImplementation2string(ctx context.Context, v interface{}) (string, error) { return graphql.UnmarshalString(v) } @@ -12048,6 +12249,97 @@ func (ec *executionContext) unmarshalOChanges2map(ctx context.Context, v interfa return v.(map[string]interface{}), nil } +func (ec *executionContext) marshalOCheckIssue8962githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐCheckIssue896(ctx context.Context, sel ast.SelectionSet, v CheckIssue896) graphql.Marshaler { + return ec._CheckIssue896(ctx, sel, &v) +} + +func (ec *executionContext) marshalOCheckIssue8962ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐCheckIssue896(ctx context.Context, sel ast.SelectionSet, v []*CheckIssue896) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + rctx := &graphql.ResolverContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithResolverContext(ctx, rctx) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalOCheckIssue8962ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐCheckIssue896(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + return ret +} + +func (ec *executionContext) marshalOCheckIssue8962ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐCheckIssue896ᚄ(ctx context.Context, sel ast.SelectionSet, v []*CheckIssue896) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + rctx := &graphql.ResolverContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithResolverContext(ctx, rctx) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNCheckIssue8962ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐCheckIssue896(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + return ret +} + +func (ec *executionContext) marshalOCheckIssue8962ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐCheckIssue896(ctx context.Context, sel ast.SelectionSet, v *CheckIssue896) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._CheckIssue896(ctx, sel, v) +} + func (ec *executionContext) marshalOCircle2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐCircle(ctx context.Context, sel ast.SelectionSet, v Circle) graphql.Marshaler { return ec._Circle(ctx, sel, &v) } diff --git a/codegen/testserver/issue896.graphql b/codegen/testserver/issue896.graphql index fff24ddb54..ed324f54ed 100644 --- a/codegen/testserver/issue896.graphql +++ b/codegen/testserver/issue896.graphql @@ -7,12 +7,12 @@ extend schema { subscription: Subscription } -type Thing {id: Int} +type CheckIssue896 {id: Int} extend type Query { - things1: [Thing!] # Note the "!" or lack thereof. + issue896a: [CheckIssue896!] # Note the "!" or lack thereof. } extend type Subscription { - things2: [Thing] # Note the "!" or lack thereof. + issue896b: [CheckIssue896] # Note the "!" or lack thereof. } diff --git a/codegen/testserver/models-gen.go b/codegen/testserver/models-gen.go index 197ca86b80..6803afdf3b 100644 --- a/codegen/testserver/models-gen.go +++ b/codegen/testserver/models-gen.go @@ -37,6 +37,10 @@ type B struct { func (B) IsTestUnion() {} +type CheckIssue896 struct { + ID *int `json:"id"` +} + type ContentPost struct { Foo *string `json:"foo"` } diff --git a/codegen/testserver/resolver.go b/codegen/testserver/resolver.go index 3572a3498e..c9cd3d52cd 100644 --- a/codegen/testserver/resolver.go +++ b/codegen/testserver/resolver.go @@ -194,6 +194,9 @@ func (r *queryResolver) Shapes(ctx context.Context) ([]Shape, error) { func (r *queryResolver) NoShape(ctx context.Context) (Shape, error) { panic("not implemented") } +func (r *queryResolver) Issue896a(ctx context.Context) ([]*CheckIssue896, error) { + panic("not implemented") +} func (r *queryResolver) MapStringInterface(ctx context.Context, in map[string]interface{}) (map[string]interface{}, error) { panic("not implemented") } @@ -263,6 +266,9 @@ func (r *subscriptionResolver) DirectiveDouble(ctx context.Context) (<-chan *str func (r *subscriptionResolver) DirectiveUnimplemented(ctx context.Context) (<-chan *string, error) { panic("not implemented") } +func (r *subscriptionResolver) Issue896b(ctx context.Context) (<-chan []*CheckIssue896, error) { + panic("not implemented") +} type userResolver struct{ *Resolver } diff --git a/codegen/testserver/stub.go b/codegen/testserver/stub.go index e33a87e10d..7956565fd6 100644 --- a/codegen/testserver/stub.go +++ b/codegen/testserver/stub.go @@ -68,6 +68,7 @@ type Stub struct { EmbeddedCase3 func(ctx context.Context) (*EmbeddedCase3, error) Shapes func(ctx context.Context) ([]Shape, error) NoShape func(ctx context.Context) (Shape, error) + Issue896a func(ctx context.Context) ([]*CheckIssue896, error) MapStringInterface func(ctx context.Context, in map[string]interface{}) (map[string]interface{}, error) MapNestedStringInterface func(ctx context.Context, in *NestedMapInput) (map[string]interface{}, error) ErrorBubble func(ctx context.Context) (*Error, error) @@ -92,6 +93,7 @@ type Stub struct { DirectiveNullableArg func(ctx context.Context, arg *int, arg2 *int, arg3 *string) (<-chan *string, error) DirectiveDouble func(ctx context.Context) (<-chan *string, error) DirectiveUnimplemented func(ctx context.Context) (<-chan *string, error) + Issue896b func(ctx context.Context) (<-chan []*CheckIssue896, error) } UserResolver struct { Friends func(ctx context.Context, obj *User) ([]*User, error) @@ -281,6 +283,9 @@ func (r *stubQuery) Shapes(ctx context.Context) ([]Shape, error) { func (r *stubQuery) NoShape(ctx context.Context) (Shape, error) { return r.QueryResolver.NoShape(ctx) } +func (r *stubQuery) Issue896a(ctx context.Context) ([]*CheckIssue896, error) { + return r.QueryResolver.Issue896a(ctx) +} func (r *stubQuery) MapStringInterface(ctx context.Context, in map[string]interface{}) (map[string]interface{}, error) { return r.QueryResolver.MapStringInterface(ctx, in) } @@ -350,6 +355,9 @@ func (r *stubSubscription) DirectiveDouble(ctx context.Context) (<-chan *string, func (r *stubSubscription) DirectiveUnimplemented(ctx context.Context) (<-chan *string, error) { return r.SubscriptionResolver.DirectiveUnimplemented(ctx) } +func (r *stubSubscription) Issue896b(ctx context.Context) (<-chan []*CheckIssue896, error) { + return r.SubscriptionResolver.Issue896b(ctx) +} type stubUser struct{ *Stub }