Skip to content

Commit

Permalink
Merge pull request #335 from 99designs/typed-interfaces
Browse files Browse the repository at this point in the history
Generate typed interfaces for gql interfaces & unions
  • Loading branch information
lwc authored Oct 2, 2018
2 parents b836a97 + d3e2755 commit bc35d73
Show file tree
Hide file tree
Showing 12 changed files with 55 additions and 33 deletions.
16 changes: 8 additions & 8 deletions Gopkg.lock

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

19 changes: 1 addition & 18 deletions codegen/interface_build.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package codegen

import (
"fmt"
"go/types"
"os"
"sort"

"github.com/vektah/gqlparser/ast"
Expand Down Expand Up @@ -51,20 +49,5 @@ func (cfg *Config) isValueReceiver(intf *NamedType, implementor *NamedType, prog
return true
}

for i := 0; i < interfaceType.NumMethods(); i++ {
intfMethod := interfaceType.Method(i)

implMethod := findMethod(implementorType, intfMethod.Name())
if implMethod == nil {
fmt.Fprintf(os.Stderr, "missing method %s on %s\n", intfMethod.Name(), implementor.GoType)
return false
}

sig := implMethod.Type().(*types.Signature)
if _, isPtr := sig.Recv().Type().(*types.Pointer); isPtr {
return false
}
}

return true
return types.Implements(implementorType, interfaceType)
}
1 change: 1 addition & 0 deletions codegen/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ type Model struct {
*NamedType
Description string
Fields []ModelField
Implements []*NamedType
}

type ModelField struct {
Expand Down
5 changes: 3 additions & 2 deletions codegen/models_build.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ func (cfg *Config) buildModels(types NamedTypes, prog *loader.Program, imports *

func (cfg *Config) obj2Model(obj *Object) Model {
model := Model{
NamedType: obj.NamedType,
Fields: []ModelField{},
NamedType: obj.NamedType,
Implements: obj.Implements,
Fields: []ModelField{},
}

model.GoType = ucFirst(obj.GQLType)
Expand Down
1 change: 1 addition & 0 deletions codegen/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type Object struct {

Fields []Field
Satisfies []string
Implements []*NamedType
ResolverInterface *Ref
Root bool
DisableConcurrency bool
Expand Down
4 changes: 4 additions & 0 deletions codegen/object_build.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ func (cfg *Config) buildObject(types NamedTypes, typ *ast.Definition, imports *I

obj.Satisfies = append(obj.Satisfies, typ.Interfaces...)

for _, intf := range cfg.schema.GetImplements(typ) {
obj.Implements = append(obj.Implements, types[intf.Name])
}

for _, field := range typ.Fields {
if typ == cfg.schema.Query && field.Name == "__type" {
obj.Fields = append(obj.Fields, Field{
Expand Down
2 changes: 1 addition & 1 deletion codegen/templates/data.go

Large diffs are not rendered by default.

9 changes: 8 additions & 1 deletion codegen/templates/models.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import (
{{ range $model := .Models }}
{{with .Description}} {{.|prefixLines "// "}} {{end}}
{{- if .IsInterface }}
type {{.GoType}} interface {}
type {{.GoType}} interface {
Is{{.GoType}}()
}
{{- else }}
type {{.GoType}} struct {
{{- range $field := .Fields }}
Expand All @@ -25,6 +27,11 @@ import (
{{- end }}
{{- end }}
}

{{- range $iface := .Implements }}
func ({{$model.GoType}}) Is{{$iface.GoType}}() {}
{{- end }}

{{- end }}
{{- end}}

Expand Down
7 changes: 7 additions & 0 deletions codegen/testserver/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import "math"

type Shape interface {
Area() float64
isShape()
}

type ShapeUnion interface {
Area() float64
isShapeUnion()
}

type Circle struct {
Expand All @@ -18,10 +20,15 @@ func (c *Circle) Area() float64 {
return c.Radius * math.Pi * math.Pi
}

func (c *Circle) isShapeUnion() {}
func (c *Circle) isShape() {}

type Rectangle struct {
Length, Width float64
}

func (r *Rectangle) Area() float64 {
return r.Length * r.Width
}
func (r *Rectangle) isShapeUnion() {}
func (r *Rectangle) isShape() {}
8 changes: 7 additions & 1 deletion example/selection/models_gen.go

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

6 changes: 6 additions & 0 deletions example/starwars/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ func (h *Human) Height(unit LengthUnit) float64 {
}
}

func (Human) IsCharacter() {}
func (Human) IsSearchResult() {}

type Review struct {
Stars int
Commentary *string
Expand All @@ -45,6 +48,9 @@ type Droid struct {
PrimaryFunction string
}

func (Droid) IsCharacter() {}
func (Droid) IsSearchResult() {}

func (r *Resolver) resolveFriendConnection(ctx context.Context, ids []string, first *int, after *string) (FriendsConnection, error) {
from := 0
if after != nil {
Expand Down
10 changes: 8 additions & 2 deletions example/starwars/models_gen.go

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

0 comments on commit bc35d73

Please sign in to comment.