Skip to content

Commit

Permalink
extract argument construction
Browse files Browse the repository at this point in the history
  • Loading branch information
vektah committed Jan 9, 2019
1 parent 4b85d1b commit 1d86f98
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 40 deletions.
2 changes: 1 addition & 1 deletion codegen/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func Generate(cfg *config.Config) error {
return errors.Wrap(err, "merging failed")
}

if err := buildModels(schema); err != nil {
if err = buildModels(schema); err != nil {
return errors.Wrap(err, "generating models failed")
}

Expand Down
2 changes: 1 addition & 1 deletion codegen/unified/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ func (g *Schema) injectIntrospectionRoots() error {
GoFieldType: GoFieldMethod,
GoReceiverName: "ec",
GoFieldName: "introspectType",
Args: []FieldArgument{
Args: []*FieldArgument{
{
GQLName: "name",
TypeReference: &TypeReference{
Expand Down
4 changes: 2 additions & 2 deletions codegen/unified/build_bind.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,8 @@ func bindVar(t types.Type, field *Field, structTag string) error {
return nil
}

func matchArgs(field *Field, params *types.Tuple) ([]FieldArgument, error) {
var newArgs []FieldArgument
func matchArgs(field *Field, params *types.Tuple) ([]*FieldArgument, error) {
var newArgs []*FieldArgument

nextArg:
for j := 0; j < params.Len(); j++ {
Expand Down
64 changes: 40 additions & 24 deletions codegen/unified/build_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
func (g *Schema) buildObject(typ *ast.Definition) (*Object, error) {
dirs, err := g.getDirectives(typ.Directives)
if err != nil {
return nil, err
return nil, errors.Wrap(err, typ.Name)
}

isRoot := typ == g.Schema.Query || typ == g.Schema.Mutation || typ == g.Schema.Subscription
Expand Down Expand Up @@ -42,14 +42,16 @@ func (g *Schema) buildObject(typ *ast.Definition) (*Object, error) {

f, err := g.buildField(obj, field)
if err != nil {
return nil, err
return nil, errors.Wrap(err, typ.Name+"."+field.Name)
}

if typ.Kind == ast.InputObject && !f.TypeReference.Definition.GQLDefinition.IsInputType() {
return nil, errors.Errorf(
"%s cannot be used as a field of %s. only input and scalar types are allowed",
"%s.%s: cannot use %s because %s is not a valid input type",
typ.Name,
field.Name,
f.Definition.GQLDefinition.Name,
obj.Definition.GQLDefinition.Name,
f.TypeReference.Definition.GQLDefinition.Kind,
)
}

Expand Down Expand Up @@ -86,7 +88,7 @@ func (g *Schema) buildField(obj *Object, field *ast.FieldDefinition) (*Field, er
var err error
f.Default, err = field.DefaultValue.Value(nil)
if err != nil {
return nil, errors.Errorf("default value for %s.%s is not valid: %s", obj.Definition.GQLDefinition.Name, field.Name, err.Error())
return nil, errors.Errorf("default value %s is not valid: %s", field.Name, err.Error())
}
}

Expand All @@ -103,30 +105,44 @@ func (g *Schema) buildField(obj *Object, field *ast.FieldDefinition) (*Field, er
}

for _, arg := range field.Arguments {
argDirs, err := g.getDirectives(arg.Directives)
newArg, err := g.buildArg(obj, arg)
if err != nil {
return nil, err
}
newArg := FieldArgument{
GQLName: arg.Name,
TypeReference: g.NamedTypes.getType(arg.Type),
Object: obj,
GoVarName: sanitizeArgName(arg.Name),
Directives: argDirs,
}
f.Args = append(f.Args, newArg)
}
return &f, nil
}

if !newArg.TypeReference.Definition.GQLDefinition.IsInputType() {
return nil, errors.Errorf("%s cannot be used as argument of %s.%s. only input and scalar types are allowed", arg.Type, obj.Definition.GQLDefinition.Name, field.Name)
}
func (g *Schema) buildArg(obj *Object, arg *ast.ArgumentDefinition) (*FieldArgument, error) {
argDirs, err := g.getDirectives(arg.Directives)
if err != nil {
return nil, err
}
newArg := FieldArgument{
GQLName: arg.Name,
TypeReference: g.NamedTypes.getType(arg.Type),
Object: obj,
GoVarName: sanitizeArgName(arg.Name),
Directives: argDirs,
}

if arg.DefaultValue != nil {
var err error
newArg.Default, err = arg.DefaultValue.Value(nil)
if err != nil {
return nil, errors.Errorf("default value for %s.%s is not valid: %s", obj.Definition.GQLDefinition.Name, field.Name, err.Error())
}
if !newArg.TypeReference.Definition.GQLDefinition.IsInputType() {
return nil, errors.Errorf(
"cannot use %s as argument %s because %s is not a valid input type",
newArg.Definition.GQLDefinition.Name,
arg.Name,
newArg.TypeReference.Definition.GQLDefinition.Kind,
)
}

if arg.DefaultValue != nil {
var err error
newArg.Default, err = arg.DefaultValue.Value(nil)
if err != nil {
return nil, errors.Errorf("default value is not valid: %s", err.Error())
}
f.Args = append(f.Args, newArg)
}
return &f, nil

return &newArg, nil
}
20 changes: 10 additions & 10 deletions codegen/unified/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,16 @@ type Object struct {

type Field struct {
*TypeReference
GQLName string // The name of the field in graphql
GoFieldType GoFieldType // The field type in go, if any
GoReceiverName string // The name of method & var receiver in go, if any
GoFieldName string // The name of the method or var in go, if any
IsResolver bool // Does this field need a resolver
Args []FieldArgument // A list of arguments to be passed to this field
MethodHasContext bool // If this is bound to a go method, does the method also take a context
NoErr bool // If this is bound to a go method, does that method have an error as the second argument
Object *Object // A link back to the parent object
Default interface{} // The default value
GQLName string // The name of the field in graphql
GoFieldType GoFieldType // The field type in go, if any
GoReceiverName string // The name of method & var receiver in go, if any
GoFieldName string // The name of the method or var in go, if any
IsResolver bool // Does this field need a resolver
Args []*FieldArgument // A list of arguments to be passed to this field
MethodHasContext bool // If this is bound to a go method, does the method also take a context
NoErr bool // If this is bound to a go method, does that method have an error as the second argument
Object *Object // A link back to the parent object
Default interface{} // The default value
Directives []*Directive
}

Expand Down
4 changes: 2 additions & 2 deletions codegen/unified/schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ import (
func TestTypeUnionAsInput(t *testing.T) {
err := generate("inputunion", `testdata/unioninput.graphqls`)

require.EqualError(t, err, "unable to build object definition: Bookmarkable! cannot be used as argument of Query.addBookmark. only input and scalar types are allowed")
require.EqualError(t, err, "unable to build object definition: Query.addBookmark: cannot use Bookmarkable as argument b because UNION is not a valid input type")
}

func TestTypeInInput(t *testing.T) {
err := generate("typeinput", `testdata/typeinput.graphqls`)

require.EqualError(t, err, "unable to build input definition: Item cannot be used as a field of BookmarkableInput. only input and scalar types are allowed")
require.EqualError(t, err, "unable to build input definition: BookmarkableInput.item: cannot use Item because OBJECT is not a valid input type")
}

func generate(name string, schemaFilename string) error {
Expand Down

0 comments on commit 1d86f98

Please sign in to comment.