Skip to content

Commit

Permalink
Reintroduce special cast case for string enums
Browse files Browse the repository at this point in the history
This reverts commit 8996066.
  • Loading branch information
lwc committed Aug 13, 2020
1 parent 8561c05 commit 86c9ea4
Show file tree
Hide file tree
Showing 9 changed files with 326 additions and 43 deletions.
41 changes: 36 additions & 5 deletions codegen/config/binder.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ func (b *Binder) PointerTo(ref *TypeReference) *TypeReference {
newRef := &TypeReference{
GO: types.NewPointer(ref.GO),
GQL: ref.GQL,
CastType: ref.CastType,
Definition: ref.Definition,
Unmarshaler: ref.Unmarshaler,
Marshaler: ref.Marshaler,
Expand All @@ -167,6 +168,7 @@ type TypeReference struct {
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
IsMarshaler bool // Does the type implement graphql.Marshaler and graphql.Unmarshaler
Expand All @@ -178,6 +180,7 @@ func (ref *TypeReference) Elem() *TypeReference {
GO: p.Elem(),
Target: ref.Target,
GQL: ref.GQL,
CastType: ref.CastType,
Definition: ref.Definition,
Unmarshaler: ref.Unmarshaler,
Marshaler: ref.Marshaler,
Expand All @@ -190,6 +193,7 @@ func (ref *TypeReference) Elem() *TypeReference {
GO: ref.GO.(*types.Slice).Elem(),
Target: ref.Target,
GQL: ref.GQL.Elem,
CastType: ref.CastType,
Definition: ref.Definition,
Unmarshaler: ref.Unmarshaler,
Marshaler: ref.Marshaler,
Expand Down Expand Up @@ -345,16 +349,27 @@ func (b *Binder) TypeReference(schemaType *ast.Type, bindTarget types.Type) (ret
return nil, err
}

fun, isFunc := obj.(*types.Func)
switch {
case isFunc:
if fun, isFunc := obj.(*types.Func); isFunc {
ref.GO = fun.Type().(*types.Signature).Params().At(0).Type()
ref.Marshaler = fun
ref.Unmarshaler = types.NewFunc(0, fun.Pkg(), "Unmarshal"+typeName, nil)
case hasMethod(obj.Type(), "MarshalGQL") && hasMethod(obj.Type(), "UnmarshalGQL"):
} else if hasMethod(obj.Type(), "MarshalGQL") && hasMethod(obj.Type(), "UnmarshalGQL") {
ref.GO = obj.Type()
ref.IsMarshaler = true
default:
} else if underlying := basicUnderlying(obj.Type()); def.IsLeafType() && underlying != nil && underlying.Kind() == types.String {
// Special case for named types wrapping strings. Used by default enum implementations.

ref.GO = obj.Type()
ref.CastType = underlying

underlyingRef, err := b.TypeReference(&ast.Type{NamedType: "String"}, nil)
if err != nil {
return nil, err
}

ref.Marshaler = underlyingRef.Marshaler
ref.Unmarshaler = underlyingRef.Unmarshaler
} else {
ref.GO = obj.Type()
}

Expand Down Expand Up @@ -431,3 +446,19 @@ func hasMethod(it types.Type, name string) bool {
}
return false
}

func basicUnderlying(it types.Type) *types.Basic {
if ptr, isPtr := it.(*types.Pointer); isPtr {
it = ptr.Elem()
}
namedType, ok := it.(*types.Named)
if !ok {
return nil
}

if basic, ok := namedType.Underlying().(*types.Basic); ok {
return basic
}

return nil
}
Loading

0 comments on commit 86c9ea4

Please sign in to comment.