Skip to content

Commit

Permalink
Fix nullability checks in new marshalling
Browse files Browse the repository at this point in the history
  • Loading branch information
Adam Scarr committed Feb 6, 2019
1 parent b3f139c commit 8047b82
Show file tree
Hide file tree
Showing 16 changed files with 3,665 additions and 2,599 deletions.
4 changes: 2 additions & 2 deletions codegen/args.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ func (ec *executionContext) {{ $name }}(ctx context.Context, rawArgs map[string]
var arg{{$i}} {{ $arg.TypeReference.GO | ref}}
if tmp, ok := rawArgs[{{$arg.Name|quote}}]; ok {
{{- if $arg.Directives }}
getArg0 := func(ctx context.Context) (interface{}, error) { return ec.unmarshal{{$arg.TypeReference.GQL.Name}}2{{ $arg.TypeReference.GO | ts }}(tmp) }
getArg0 := func(ctx context.Context) (interface{}, error) { return ec.{{ $arg.TypeReference.UnmarshalFunc }}(tmp) }

{{- range $i, $directive := $arg.Directives }}
getArg{{add $i 1}} := func(ctx context.Context) (res interface{}, err error) {
Expand All @@ -30,7 +30,7 @@ func (ec *executionContext) {{ $name }}(ctx context.Context, rawArgs map[string]
return nil, fmt.Errorf(`unexpected type %T from directive, should be {{ $arg.TypeReference.GO }}`, tmp)
}
{{- else }}
arg{{$i}}, err = ec.unmarshal{{$arg.TypeReference.GQL.Name}}2{{ $arg.TypeReference.GO | ts }}(tmp)
arg{{$i}}, err = ec.{{ $arg.TypeReference.UnmarshalFunc }}(tmp)
if err != nil {
return nil, err
}
Expand Down
52 changes: 48 additions & 4 deletions codegen/config/binder.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"regexp"
"strings"

"github.com/99designs/gqlgen/codegen/templates"

"github.com/99designs/gqlgen/internal/code"
"github.com/pkg/errors"
"github.com/vektah/gqlparser/ast"
Expand Down Expand Up @@ -152,6 +154,29 @@ type TypeReference struct {
Unmarshaler *types.Func // When using external marshalling functions this will point to the Unmarshal function
}

func (ref TypeReference) Elem() *TypeReference {
if p, isPtr := ref.GO.(*types.Pointer); isPtr {
return &TypeReference{
GO: p.Elem(),
GQL: ref.GQL,
Definition: ref.Definition,
Unmarshaler: ref.Unmarshaler,
Marshaler: ref.Marshaler,
}
}

if s, isSlice := ref.GO.(*types.Slice); isSlice {
return &TypeReference{
GO: s.Elem(),
GQL: ref.GQL.Elem,
Definition: ref.Definition,
Unmarshaler: ref.Unmarshaler,
Marshaler: ref.Marshaler,
}
}
return nil
}

func (t TypeReference) IsPtr() bool {
_, isPtr := t.GO.(*types.Pointer)
return isPtr
Expand Down Expand Up @@ -190,18 +215,37 @@ func (t TypeReference) SelfMarshalling() bool {
return false
}

func (t TypeReference) NeedsUnmarshaler() bool {
func (t TypeReference) UniquenessKey() string {
var nullability = "O"
if t.GQL.NonNull {
nullability = "N"
}

return nullability + t.Definition.Name + "2" + templates.TypeIdentifier(t.GO)
}

func (t TypeReference) MarshalFunc() string {
if t.Definition == nil {
panic(errors.New("Definition missing for " + t.GQL.Name()))
}
return t.Definition.IsInputType()

if t.Definition.Kind == ast.InputObject {
return ""
}

return "marshal" + t.UniquenessKey()
}

func (t TypeReference) NeedsMarshaler() bool {
func (t TypeReference) UnmarshalFunc() string {
if t.Definition == nil {
panic(errors.New("Definition missing for " + t.GQL.Name()))
}
return t.Definition.Kind != ast.InputObject

if !t.Definition.IsInputType() {
return ""
}

return "unmarshal" + t.UniquenessKey()
}

func (b *Binder) PushRef(ret *TypeReference) {
Expand Down
4 changes: 2 additions & 2 deletions codegen/field.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
w.Write([]byte{'{'})
graphql.MarshalString(field.Alias).MarshalGQL(w)
w.Write([]byte{':'})
ec.marshal{{ $field.TypeReference.Definition.Name }}2{{ $field.TypeReference.GO | ts }}(ctx, field.Selections, res).MarshalGQL(w)
ec.{{ $field.TypeReference.MarshalFunc }}(ctx, field.Selections, res).MarshalGQL(w)
w.Write([]byte{'}'})
})
}
Expand Down Expand Up @@ -81,7 +81,7 @@
res := resTmp.({{$field.TypeReference.GO | ref}})
rctx.Result = res
ctx = ec.Tracer.StartFieldChildExecution(ctx)
return ec.marshal{{ $field.TypeReference.Definition.Name }}2{{ $field.TypeReference.GO | ts }}(ctx, field.Selections, res)
return ec.{{ $field.TypeReference.MarshalFunc }}(ctx, field.Selections, res)
}
{{ end }}

Expand Down
2 changes: 1 addition & 1 deletion codegen/input.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
{{- range $field := .Fields }}
case {{$field.Name|quote}}:
var err error
it.{{$field.GoFieldName}}, err = ec.unmarshal{{$field.TypeReference.GQL.Name}}2{{ $field.TypeReference.GO | ts }}(v)
it.{{$field.GoFieldName}}, err = ec.{{ $field.TypeReference.UnmarshalFunc }}(v)
if err != nil {
return it, err
}
Expand Down
Loading

0 comments on commit 8047b82

Please sign in to comment.