interface_build.go

 1package codegen
 2
 3import (
 4	"go/types"
 5	"sort"
 6
 7	"github.com/vektah/gqlparser/ast"
 8	"golang.org/x/tools/go/loader"
 9)
10
11func (cfg *Config) buildInterfaces(types NamedTypes, prog *loader.Program) []*Interface {
12	var interfaces []*Interface
13	for _, typ := range cfg.schema.Types {
14		if typ.Kind == ast.Union || typ.Kind == ast.Interface {
15			interfaces = append(interfaces, cfg.buildInterface(types, typ, prog))
16		}
17	}
18
19	sort.Slice(interfaces, func(i, j int) bool {
20		return interfaces[i].GQLType < interfaces[j].GQLType
21	})
22
23	return interfaces
24}
25
26func (cfg *Config) buildInterface(types NamedTypes, typ *ast.Definition, prog *loader.Program) *Interface {
27	i := &Interface{NamedType: types[typ.Name]}
28
29	for _, implementor := range cfg.schema.GetPossibleTypes(typ) {
30		t := types[implementor.Name]
31
32		i.Implementors = append(i.Implementors, InterfaceImplementor{
33			NamedType:     t,
34			ValueReceiver: cfg.isValueReceiver(types[typ.Name], t, prog),
35		})
36	}
37
38	return i
39}
40
41func (cfg *Config) isValueReceiver(intf *NamedType, implementor *NamedType, prog *loader.Program) bool {
42	interfaceType, err := findGoInterface(prog, intf.Package, intf.GoType)
43	if interfaceType == nil || err != nil {
44		return true
45	}
46
47	implementorType, err := findGoNamedType(prog, implementor.Package, implementor.GoType)
48	if implementorType == nil || err != nil {
49		return true
50	}
51
52	return types.Implements(implementorType, interfaceType)
53}