Skip to content

Commit

Permalink
Bind directly to pointer types when possible, instead of always bindi…
Browse files Browse the repository at this point in the history
…ng to value types
  • Loading branch information
lwc committed Aug 12, 2020
1 parent 39a12e0 commit 196954b
Show file tree
Hide file tree
Showing 22 changed files with 872 additions and 748 deletions.
8 changes: 8 additions & 0 deletions codegen/config/binder.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ type TypeReference struct {
Definition *ast.Definition
GQL *ast.Type
GO types.Type
Target types.Type
CastType types.Type // Before calling marshalling functions cast from/to this base type
Marshaler *types.Func // When using external marshalling functions this will point to the Marshal function
Unmarshaler *types.Func // When using external marshalling functions this will point to the Unmarshal function
Expand All @@ -177,6 +178,7 @@ func (ref *TypeReference) Elem() *TypeReference {
if p, isPtr := ref.GO.(*types.Pointer); isPtr {
return &TypeReference{
GO: p.Elem(),
Target: ref.Target,
GQL: ref.GQL,
CastType: ref.CastType,
Definition: ref.Definition,
Expand All @@ -189,6 +191,7 @@ func (ref *TypeReference) Elem() *TypeReference {
if ref.IsSlice() {
return &TypeReference{
GO: ref.GO.(*types.Slice).Elem(),
Target: ref.Target,
GQL: ref.GQL.Elem,
CastType: ref.CastType,
Definition: ref.Definition,
Expand Down Expand Up @@ -266,6 +269,10 @@ func (t *TypeReference) UnmarshalFunc() string {
return "unmarshal" + t.UniquenessKey()
}

func (t *TypeReference) IsTargetNilable() bool {
return IsNilable(t.Target)
}

func (b *Binder) PushRef(ret *TypeReference) {
b.References = append(b.References, ret)
}
Expand Down Expand Up @@ -366,6 +373,7 @@ func (b *Binder) TypeReference(schemaType *ast.Type, bindTarget types.Type) (ret
ref.GO = obj.Type()
}

ref.Target = ref.GO
ref.GO = b.CopyModifiersFromAst(schemaType, ref.GO)

if bindTarget != nil {
Expand Down
337 changes: 104 additions & 233 deletions codegen/testserver/generated.go

Large diffs are not rendered by default.

8 changes: 2 additions & 6 deletions codegen/testserver/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,9 +332,7 @@ func (r *wrappedSliceResolver) Get(ctx context.Context, obj WrappedSlice, idx in
}

// BackedByInterface returns BackedByInterfaceResolver implementation.
func (r *Resolver) BackedByInterface() BackedByInterfaceResolver {
return &backedByInterfaceResolver{r}
}
func (r *Resolver) BackedByInterface() BackedByInterfaceResolver { return &backedByInterfaceResolver{r} }

// Errors returns ErrorsResolver implementation.
func (r *Resolver) Errors() ErrorsResolver { return &errorsResolver{r} }
Expand All @@ -349,9 +347,7 @@ func (r *Resolver) ModelMethods() ModelMethodsResolver { return &modelMethodsRes
func (r *Resolver) Mutation() MutationResolver { return &mutationResolver{r} }

// OverlappingFields returns OverlappingFieldsResolver implementation.
func (r *Resolver) OverlappingFields() OverlappingFieldsResolver {
return &overlappingFieldsResolver{r}
}
func (r *Resolver) OverlappingFields() OverlappingFieldsResolver { return &overlappingFieldsResolver{r} }

// Panics returns PanicsResolver implementation.
func (r *Resolver) Panics() PanicsResolver { return &panicsResolver{r} }
Expand Down
6 changes: 5 additions & 1 deletion codegen/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ func (b *builder) buildTypes() map[string]*config.TypeReference {
}
ret[key] = ref

ref = ref.Elem()
if ref.IsSlice() {
ref = ref.Elem()
} else {
break
}
}
}
return ret
Expand Down
48 changes: 36 additions & 12 deletions codegen/type.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@
{{- if and $type.IsNilable (not $type.GQL.NonNull) }}
if v == nil { return nil, nil }
{{- end }}
{{- if $type.IsPtr }}
res, err := ec.{{ $type.Elem.UnmarshalFunc }}(ctx, v)
return &res, graphql.WrapErrorWithInputPath(ctx, err)
{{- else if $type.IsSlice }}
{{- if $type.IsSlice }}
var vSlice []interface{}
if v != nil {
if tmp1, ok := v.([]interface{}); ok {
Expand All @@ -31,19 +28,41 @@
{{- if $type.CastType }}
tmp, err := {{ $type.Unmarshaler | call }}(v)
return {{ $type.GO | ref }}(tmp), graphql.WrapErrorWithInputPath(ctx, err)
{{- else if and $type.IsTargetNilable (not $type.IsNilable) }}
tmp, err := {{ $type.Unmarshaler | call }}(v)
res := *tmp
return res, graphql.WrapErrorWithInputPath(ctx, err)
{{- else if and (not $type.IsTargetNilable) $type.IsNilable }}
tmp, err := {{ $type.Unmarshaler | call }}(v)
res := &tmp
return res, graphql.WrapErrorWithInputPath(ctx, err)
{{- else}}
res, err := {{ $type.Unmarshaler | call }}(v)
return res, graphql.WrapErrorWithInputPath(ctx, err)
{{- end }}
{{- else if eq ($type.GO | ref) "map[string]interface{}" }}
return v.(map[string]interface{}), nil
{{- else if $type.IsMarshaler }}
var res {{ $type.GO | ref }}
{{- if $type.IsNilable }}
var res = new({{ $type.Elem.GO | ref }})
{{- else}}
var res {{ $type.GO | ref }}
{{- end }}
err := res.UnmarshalGQL(v)
return res, graphql.WrapErrorWithInputPath(ctx, err)
{{- else }}
res, err := ec.unmarshalInput{{ $type.GQL.Name }}(ctx, v)
return res, graphql.WrapErrorWithInputPath(ctx, err)
{{- if and $type.IsTargetNilable (not $type.IsNilable) }}
tmp, err := ec.unmarshalInput{{ $type.GQL.Name }}(ctx, v)
res := *tmp
return res, graphql.WrapErrorWithInputPath(ctx, err)
{{- else if and (not $type.IsTargetNilable) $type.IsNilable }}
tmp, err := ec.unmarshalInput{{ $type.GQL.Name }}(ctx, v)
res := &tmp
return res, graphql.WrapErrorWithInputPath(ctx, err)
{{- else}}
res, err := ec.unmarshalInput{{ $type.GQL.Name }}(ctx, v)
return res, graphql.WrapErrorWithInputPath(ctx, err)
{{- end }}
{{- end }}
{{- end }}
}
Expand Down Expand Up @@ -110,18 +129,23 @@
{{- if $type.IsMarshaler }}
return v
{{- else if $type.Marshaler }}
{{- if $type.IsPtr }}
return ec.{{ $type.Elem.MarshalFunc }}(ctx, sel, *v)
{{- else if $type.GQL.NonNull }}
res := {{ $type.Marshaler | call }}({{- if $type.CastType }}{{ $type.CastType | ref }}(v){{else}}v{{- end }})
{{- if and $type.IsTargetNilable (not $type.IsNilable) }}
in := &v
{{- else if and (not $type.IsTargetNilable) $type.IsNilable }}
in := *v
{{- else}}
in := v
{{- end }}
{{- if $type.GQL.NonNull }}
res := {{ $type.Marshaler | call }}({{- if $type.CastType }}{{ $type.CastType | ref }}(in){{else}}in{{- end }})
if res == graphql.Null {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "must not be null")
}
}
return res
{{- else }}
return {{ $type.Marshaler | call }}({{- if $type.CastType }}{{ $type.CastType | ref }}(v){{else}}v{{- end }})
return {{ $type.Marshaler | call }}({{- if $type.CastType }}{{ $type.CastType | ref }}(in){{else}}in{{- end }})
{{- end }}
{{- else }}
return ec._{{$type.Definition.Name}}(ctx, sel, {{ if not $type.IsNilable}}&{{end}} v)
Expand Down
52 changes: 26 additions & 26 deletions example/chat/generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 196954b

Please sign in to comment.