Skip to content

Commit

Permalink
Fix Interface Slice Getter Generation (#2332)
Browse files Browse the repository at this point in the history
* Make modelgen test fail if generated doesn't build
Added returning list of interface to modelgen test schema

* Implement slice copying when returning interface slices

* Re-generate to satisfy the linter

Co-authored-by: Bill Rose <neptoess@gmail.com>
  • Loading branch information
neptoess and Bill Rose committed Aug 20, 2022
1 parent aee57b4 commit 2b58401
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 14 deletions.
48 changes: 42 additions & 6 deletions _examples/selection/models_gen.go

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

33 changes: 25 additions & 8 deletions plugin/modelgen/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,6 @@ func (m *Plugin) MutateConfig(cfg *config.Config) error {
return ""
}

getter := fmt.Sprintf("func (this %s) Get%s() %s { return ", templates.ToGo(model.Name), field.GoName, templates.CurrentImports.LookupType(field.Type))
_, interfaceFieldTypeIsPointer := field.Type.(*types.Pointer)
var structFieldTypeIsPointer bool
for _, f := range model.Fields {
Expand All @@ -238,15 +237,33 @@ func (m *Plugin) MutateConfig(cfg *config.Config) error {
break
}
}
goType := templates.CurrentImports.LookupType(field.Type)
if strings.HasPrefix(goType, "[]") {
getter := fmt.Sprintf("func (this %s) Get%s() %s {\n", templates.ToGo(model.Name), field.GoName, goType)
getter += fmt.Sprintf("\tif this.%s == nil { return nil }\n", field.GoName)
getter += fmt.Sprintf("\tinterfaceSlice := make(%s, 0, len(this.%s))\n", goType, field.GoName)
getter += fmt.Sprintf("\tfor _, concrete := range this.%s { interfaceSlice = append(interfaceSlice, ", field.GoName)
if interfaceFieldTypeIsPointer && !structFieldTypeIsPointer {
getter += "&"
} else if !interfaceFieldTypeIsPointer && structFieldTypeIsPointer {
getter += "*"
}
getter += "concrete) }\n"
getter += "\treturn interfaceSlice\n"
getter += "}"
return getter
} else {
getter := fmt.Sprintf("func (this %s) Get%s() %s { return ", templates.ToGo(model.Name), field.GoName, goType)

if interfaceFieldTypeIsPointer && !structFieldTypeIsPointer {
getter += "&"
} else if !interfaceFieldTypeIsPointer && structFieldTypeIsPointer {
getter += "*"
}
if interfaceFieldTypeIsPointer && !structFieldTypeIsPointer {
getter += "&"
} else if !interfaceFieldTypeIsPointer && structFieldTypeIsPointer {
getter += "*"
}

getter += fmt.Sprintf("this.%s }", field.GoName)
return getter
getter += fmt.Sprintf("this.%s }", field.GoName)
return getter
}
}
funcMap := template.FuncMap{
"getInterfaceByName": getInterfaceByName,
Expand Down
14 changes: 14 additions & 0 deletions plugin/modelgen/models_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package modelgen

import (
"errors"
"go/ast"
"go/parser"
"go/token"
"os"
"os/exec"
"path/filepath"
"sort"
"strings"
Expand All @@ -27,6 +29,7 @@ func TestModelGeneration(t *testing.T) {
FieldHook: defaultFieldMutateHook,
}
require.NoError(t, p.MutateConfig(cfg))
require.NoError(t, goBuild(t, "./out/"))

require.True(t, cfg.Models.UserDefined("MissingTypeNotNull"))
require.True(t, cfg.Models.UserDefined("MissingTypeNullable"))
Expand Down Expand Up @@ -330,3 +333,14 @@ func parseAst(path string) (*ast.Package, error) {
}
return pkgs["out"], nil
}

func goBuild(t *testing.T, path string) error {
t.Helper()
cmd := exec.Command("go", "build", path)
out, err := cmd.CombinedOutput()
if err != nil {
return errors.New(string(out))
}

return nil
}
33 changes: 33 additions & 0 deletions plugin/modelgen/out/generated.go

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

33 changes: 33 additions & 0 deletions plugin/modelgen/out_struct_pointers/generated.go

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

10 changes: 10 additions & 0 deletions plugin/modelgen/testdata/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,13 @@ type RenameFieldTest {
badName: String!
otherField: String!
}

interface ArrayOfA {
trickyField: [A!]!
trickyFieldPointer: [A]
}

type ImplArrayOfA implements ArrayOfA {
trickyField: [CDImplemented!]!
trickyFieldPointer: [CDImplemented]
}

0 comments on commit 2b58401

Please sign in to comment.