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}