diff options
Diffstat (limited to 'vendor/github.com/99designs/gqlgen/codegen/interface_build.go')
-rw-r--r-- | vendor/github.com/99designs/gqlgen/codegen/interface_build.go | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/vendor/github.com/99designs/gqlgen/codegen/interface_build.go b/vendor/github.com/99designs/gqlgen/codegen/interface_build.go new file mode 100644 index 00000000..9f4a4ff4 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/interface_build.go @@ -0,0 +1,70 @@ +package codegen + +import ( + "fmt" + "go/types" + "os" + "sort" + + "github.com/vektah/gqlparser/ast" + "golang.org/x/tools/go/loader" +) + +func (cfg *Config) buildInterfaces(types NamedTypes, prog *loader.Program) []*Interface { + var interfaces []*Interface + for _, typ := range cfg.schema.Types { + if typ.Kind == ast.Union || typ.Kind == ast.Interface { + interfaces = append(interfaces, cfg.buildInterface(types, typ, prog)) + } + } + + sort.Slice(interfaces, func(i, j int) bool { + return interfaces[i].GQLType < interfaces[j].GQLType + }) + + return interfaces +} + +func (cfg *Config) buildInterface(types NamedTypes, typ *ast.Definition, prog *loader.Program) *Interface { + i := &Interface{NamedType: types[typ.Name]} + + for _, implementor := range cfg.schema.GetPossibleTypes(typ) { + t := types[implementor.Name] + + i.Implementors = append(i.Implementors, InterfaceImplementor{ + NamedType: t, + ValueReceiver: cfg.isValueReceiver(types[typ.Name], t, prog), + }) + } + + return i +} + +func (cfg *Config) isValueReceiver(intf *NamedType, implementor *NamedType, prog *loader.Program) bool { + interfaceType, err := findGoInterface(prog, intf.Package, intf.GoType) + if interfaceType == nil || err != nil { + return true + } + + implementorType, err := findGoNamedType(prog, implementor.Package, implementor.GoType) + if implementorType == nil || err != nil { + 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 +} |