-
Notifications
You must be signed in to change notification settings - Fork 117
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add "struct_references" configuration #155
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -77,6 +77,17 @@ context_type: context.Context | |||||
# without making a query. | ||||||
client_getter: "github.com/you/yourpkg.GetClient" | ||||||
|
||||||
|
||||||
# if set, fields with a complex type will default to having | ||||||
# the "pointer: true, omitempty: true" flag | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
# | ||||||
# This can be useful for complex schema where it would be burdensome | ||||||
# to manually set the flags on a large number of fields | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
# | ||||||
# Defaults to false. | ||||||
use_weak_references: boolean | ||||||
|
||||||
|
||||||
# A map from GraphQL type name to Go fully-qualified type name to override | ||||||
# the Go type genqlient will use for this GraphQL type. | ||||||
# | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -174,7 +174,7 @@ func (g *generator) convertArguments( | |
// names.go) and the selection-set (we use all the input type's fields, | ||
// and so on recursively). See also the `case ast.InputObject` in | ||
// convertDefinition, below. | ||
goTyp, err := g.convertType(nil, arg.Type, nil, options, queryOptions) | ||
goTyp, err := g.convertType(nil, arg.Type, false, nil, options, queryOptions) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh interesting, do you think we don't want to apply this to arguments? I would think we would; while of course there it's easier to set it seems like a more consistent default would be better. If you feel this is clearer I'm ok with that. Either way probably worth an explicit mention in the docs. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm, yes Interesting. I hadn't really considered allowing arguments, but don't see why not. Plus, allowing it will simplify the code by removing the need to pass around the |
||
if err != nil { | ||
return nil, err | ||
} | ||
|
@@ -218,6 +218,7 @@ func (g *generator) convertArguments( | |
func (g *generator) convertType( | ||
namePrefix *prefixList, | ||
typ *ast.Type, | ||
isStructField bool, | ||
selectionSet ast.SelectionSet, | ||
options, queryOptions *genqlientDirective, | ||
) (goType, error) { | ||
|
@@ -235,16 +236,23 @@ func (g *generator) convertType( | |
if typ.Elem != nil { | ||
// Type is a list. | ||
elem, err := g.convertType( | ||
namePrefix, typ.Elem, selectionSet, options, queryOptions) | ||
namePrefix, typ.Elem, isStructField, selectionSet, options, queryOptions) | ||
return &goSliceType{elem}, err | ||
} | ||
|
||
// If this is a builtin type or custom scalar, just refer to it. | ||
def := g.schema.Types[typ.Name()] | ||
|
||
goTyp, err := g.convertDefinition( | ||
namePrefix, def, typ.Position, selectionSet, options, queryOptions) | ||
|
||
if options.GetPointer() { | ||
if g.getWeakReference(options, isStructField, def) { | ||
if options.Omitempty == nil { | ||
oe := true | ||
options.Omitempty = &oe | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mutating this seems a bit awkward. Can we instead just put this in where we call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed, but I played with a few different options here but didn't find anything better. GetOmitempty is called in a few spots, and we'd have to pass the Config and field definition into it and then duplicating the logic of the The updated check I've came up with here is a bit cleaner IMO, so see what you think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, fair enough! |
||
} | ||
goTyp = &goPointerType{goTyp} | ||
} else if options.GetPointer() { | ||
// Whatever we get, wrap it in a pointer. (Because of the way the | ||
// options work, recursing here isn't as connvenient.) | ||
// Note this does []*T or [][]*T, not e.g. *[][]T. See #16. | ||
|
@@ -253,6 +261,18 @@ func (g *generator) convertType( | |
return goTyp, err | ||
} | ||
|
||
// getWeakReference decides if a field should be of pointer type and have the omitempty flag set. | ||
func (g *generator) getWeakReference( | ||
options *genqlientDirective, | ||
isStructField bool, | ||
def *ast.Definition, | ||
) bool { | ||
return options.Pointer == nil && | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this will be a little confusing in that it will mean if you do There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, you're correct. The logic is slightly flawed here as you describe. I'll rework |
||
isStructField && | ||
g.Config.WeakReferences && | ||
len(def.Fields) > 0 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh so actually a question here is whether There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great catch, I hadn't considered the interface-typed fields. I don't see why we shouldn't use pointers for those, that way the rule doesn't have any gotchas There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They just tend to be awkward in that you have to explicitly dereference to call the interface's methods (i.e. Another question that we had discussed in the issue is whether it applies to output objects. I think "what is easiest to explain" is also a good criterion there, but it could go either way (if inputs, we'd call it "input_references" and it makes the interfaces question moot since GraphQL doesn't have interfaces in inputs). |
||
} | ||
|
||
// convertDefinition decides the Go type we will generate corresponding to a | ||
// particular GraphQL named type. | ||
// | ||
|
@@ -404,7 +424,7 @@ func (g *generator) convertDefinition( | |
// will be ignored? We know field.Type is a scalar, enum, or input | ||
// type. But plumbing that is a bit tricky in practice. | ||
fieldGoType, err := g.convertType( | ||
namePrefix, field.Type, nil, fieldOptions, queryOptions) | ||
namePrefix, field.Type, true, nil, fieldOptions, queryOptions) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
@@ -827,7 +847,7 @@ func (g *generator) convertField( | |
namePrefix = nextPrefix(namePrefix, field) | ||
|
||
fieldGoType, err := g.convertType( | ||
namePrefix, field.Definition.Type, field.SelectionSet, | ||
namePrefix, field.Definition.Type, true, field.SelectionSet, | ||
fieldOptions, queryOptions) | ||
if err != nil { | ||
return nil, err | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(I think it's worth being explicit what types we mean.)