Skip to content

Commit

Permalink
Add ability to customize resolvergen behavior using additional plugins (
Browse files Browse the repository at this point in the history
#2516)

* Add ability to customize resolvergen behavior using additional plugins

* Add field.GoResultName()

---------

Co-authored-by: Brian Kamotho <zshrlu@gmail.com>
  • Loading branch information
shrdlu68 and Brian Kamotho authored Jan 31, 2023
1 parent 356f4f9 commit cf1607a
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 3 deletions.
6 changes: 5 additions & 1 deletion api/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,11 @@ func Generate(cfg *config.Config, option ...Option) error {
}
}
// Merge again now that the generated models have been injected into the typemap
data, err := codegen.BuildData(cfg)
data_plugins := make([]interface{}, len(plugins))
for index := range plugins {
data_plugins[index] = plugins[index]
}
data, err := codegen.BuildData(cfg, data_plugins...)
if err != nil {
return fmt.Errorf("merging type systems failed: %w", err)
}
Expand Down
4 changes: 3 additions & 1 deletion codegen/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type Data struct {
MutationRoot *Object
SubscriptionRoot *Object
AugmentedSources []AugmentedSource
Plugins []interface{}
}

func (d *Data) HasEmbeddableSources() bool {
Expand Down Expand Up @@ -76,7 +77,7 @@ func (d *Data) Directives() DirectiveList {
return res
}

func BuildData(cfg *config.Config) (*Data, error) {
func BuildData(cfg *config.Config, plugins ...interface{}) (*Data, error) {
// We reload all packages to allow packages to be compared correctly.
cfg.ReloadAllPackages()

Expand Down Expand Up @@ -105,6 +106,7 @@ func BuildData(cfg *config.Config) (*Data, error) {
AllDirectives: dataDirectives,
Schema: b.Schema,
Interfaces: map[string]*Interface{},
Plugins: plugins,
}

for _, schemaType := range b.Schema.Types {
Expand Down
15 changes: 15 additions & 0 deletions codegen/field.go
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,14 @@ func (f *Field) ResolverType() string {
return fmt.Sprintf("%s().%s(%s)", f.Object.Definition.Name, f.GoFieldName, f.CallArgs())
}

func (f *Field) IsInputObject() bool {
return f.Object.Kind == ast.InputObject
}

func (f *Field) IsRoot() bool {
return f.Object.Root
}

func (f *Field) ShortResolverDeclaration() string {
return f.ShortResolverSignature(nil)
}
Expand Down Expand Up @@ -544,6 +552,13 @@ func (f *Field) ShortResolverSignature(ft *goast.FuncType) string {
return res
}

func (f *Field) GoResultName() (string, bool) {
name := fmt.Sprintf("%v", f.TypeReference.GO)
splits := strings.Split(name, "/")

return splits[len(splits)-1], strings.HasPrefix(name, "[]")
}

func (f *Field) ComplexitySignature() string {
res := "func(childComplexity int"
for _, arg := range f.Args {
Expand Down
10 changes: 10 additions & 0 deletions codegen/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,16 @@ func (o *Object) Description() string {
return o.Definition.Description
}

func (o *Object) HasField(name string) bool {
for _, f := range o.Fields {
if f.Name == name {
return true
}
}

return false
}

func (os Objects) ByName(name string) *Object {
for i, o := range os {
if strings.EqualFold(o.Definition.Name, name) {
Expand Down
5 changes: 5 additions & 0 deletions plugin/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,8 @@ type EarlySourceInjector interface {
type LateSourceInjector interface {
InjectSourceLate(schema *ast.Schema) *ast.Source
}

// Implementer is used to generate code inside resolvers
type ResolverImplementer interface {
Implement(field *codegen.Field) string
}
19 changes: 18 additions & 1 deletion plugin/resolvergen/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,29 @@ func (m *Plugin) generatePerSchema(data *codegen.Data) error {

structName := templates.LcFirst(o.Name) + templates.UcFirst(data.Config.Resolver.Type)
comment := strings.TrimSpace(strings.TrimLeft(rewriter.GetMethodComment(structName, f.GoFieldName), `\`))

if comment == "" {
comment = fmt.Sprintf("%v is the resolver for the %v field.", f.GoFieldName, f.Name)
}
implementation := strings.TrimSpace(rewriter.GetMethodBody(structName, f.GoFieldName))
if implementation == "" {
implementation = fmt.Sprintf("panic(fmt.Errorf(\"not implemented: %v - %v\"))", f.GoFieldName, f.Name)
// Check for Implementer Plugin
var resolver_implementer plugin.ResolverImplementer
var exists bool
for _, p := range data.Plugins {
if p_cast, ok := p.(plugin.ResolverImplementer); ok {
resolver_implementer = p_cast
exists = true
break
}
}

if exists {
implementation = resolver_implementer.Implement(f)
} else {
implementation = fmt.Sprintf("panic(fmt.Errorf(\"not implemented: %v - %v\"))", f.GoFieldName, f.Name)
}

}

resolver := Resolver{o, f, rewriter.GetPrevDecl(structName, f.GoFieldName), comment, implementation}
Expand Down

0 comments on commit cf1607a

Please sign in to comment.