Skip to content

Commit

Permalink
fix alias regression in 546714b
Browse files Browse the repository at this point in the history
also uses the underlying definition for variable names in pointer fields
  • Loading branch information
switchupcb committed Jun 7, 2022
1 parent 6e8e8c5 commit 7b25c1c
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 52 deletions.
12 changes: 12 additions & 0 deletions cli/parser/field.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ func parseField(typ types.Type) *models.Field {
}

field.Definition = models.CollectionPointer + collectedDefinition(elemfield)
field.VariableName = "." + alphastring(elemfield.Definition)

case *types.Array:
field.Definition = "[" + fmt.Sprint(x.Len()) + "]" + collectedDefinition(parseField(x.Elem()))
Expand Down Expand Up @@ -200,5 +201,16 @@ func collectedDefinition(collected *models.Field) string {
return collected.Definition
}

// when a setup file imports the package it will output to,
// do NOT reference the fields defined in the output package, by package.
if outputPkgPath != "" && collected.Import == outputPkgPath {
return collected.Definition
}

// when a field's import uses an alias, reassign the package reference.
if aliasPkg, ok := aliasImportMap[collected.Import]; ok {
return aliasPkg + "." + collected.Definition
}

return collected.FullDefinition()
}
65 changes: 42 additions & 23 deletions cli/parser/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,32 @@ var (

// setupPkgPath represents the current path of the setup file's package.
//
// setupPkgPath is used to remove package references from collected types in collections
// that will be used in the generated file's package (equal to the setup file's package).
// setupPkgPath is used to remove package references from types that will be
// used in the generated file's package (equal to the setup file's package).
//
// setupPkgPath is referenced while parsing collected type definitions for collection fields,
// and while setting package references for non-collection fields after parsing.
//
// i.e `Collections` parsed as `copygen.Collections` in the setup file's package copygen,
// output as `Collections` in the generated file's package copygen.
setupPkgPath string

// outputPkgPath represents the generated file's package path.
//
// outputPkgPath is used to remove package references from types that are imported
// (in the setup file) from the generated file's package.
//
// outputPkgPath is referenced while parsing collected type definitions for collection fields,
// and while setting package references for non-collection fields after parsing.
outputPkgPath string

// aliasImportMap represents a map of import paths to package names.
//
// aliasImportMap is used to assign the correct package reference to an aliased field.
//
// aliasImportMap is referenced while parsing collected type definitions for collection fields,
// and while setting package references for non-collection fields after parsing.
aliasImportMap map[string]string
)

// SetupCache sets up the parser's global cache.
Expand Down Expand Up @@ -98,6 +118,20 @@ func Parse(gen *models.Generator) error {
}
setupPkgPath = p.Pkgs[0].PkgPath

// determine the output file package path.
outputPkgs, _ := packages.Load(&packages.Config{Mode: packages.NeedName}, "file="+gen.Outpath)
if len(outputPkgs) > 0 {
outputPkgPath = outputPkgs[0].PkgPath
}

// set the aliasImportMap.
aliasImportMap = make(map[string]string, len(p.Config.SetupFile.Imports))
for _, imp := range p.Config.SetupFile.Imports {
if imp.Name != nil {
aliasImportMap[imp.Path.Value[1:len(imp.Path.Value)-1]] = imp.Name.Name
}
}

// find a new instance of a copygen AST since the old one has its comments removed.
var newCopygen *ast.InterfaceType
for _, decl := range p.Pkgs[0].Syntax[0].Decls {
Expand All @@ -120,8 +154,8 @@ func Parse(gen *models.Generator) error {
return fmt.Errorf("%w", err)
}

// rename fields' packages using imports.
p.setPackages(gen)
// rename non-collection fields' packages using imports.
setPackages(gen)

// Write the Keep.
buf := new(bytes.Buffer)
Expand All @@ -133,29 +167,14 @@ func Parse(gen *models.Generator) error {

// reset global variables.
setupPkgPath = ""
outputPkgPath = ""
aliasImportMap = nil

return nil
}

// setFieldPackage sets the packages for all fields in a generator using names from the setup file.
func (p *Parser) setPackages(gen *models.Generator) {

// determine the output file package path.
var outputPkgPath string
pkgs, _ := packages.Load(&packages.Config{Mode: packages.NeedName}, "file="+gen.Outpath)
if len(pkgs) > 0 {
outputPkgPath = pkgs[0].PkgPath
}

// adjust the packages of each field where necessary.
imports := p.Config.SetupFile.Imports
aliasImportMap := make(map[string]string, len(imports))
for _, imp := range imports {
if imp.Name != nil {
aliasImportMap[imp.Path.Value[1:len(imp.Path.Value)-1]] = imp.Name.Name
}
}

// setPackages sets the packages for all fields in a generator using names from the setup file.
func setPackages(gen *models.Generator) {
for _, function := range gen.Functions {
functionTypes := [][]models.Type{
function.From,
Expand Down
4 changes: 3 additions & 1 deletion cli/parser/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ func parseTypeField(vars *types.Tuple) []models.Type {
for i := 0; i < vars.Len(); i++ {
field := parseField(vars.At(i).Type()).Deepcopy(nil)
field.Name = vars.At(i).Name()
field.VariableName = "." + alphastring(field.Definition)
if !field.IsPointer() {
field.VariableName = "." + alphastring(field.Definition)
}
types[i] = models.Type{Field: field}
}

Expand Down
56 changes: 28 additions & 28 deletions examples/_tests/multi/copygen.go

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

0 comments on commit 7b25c1c

Please sign in to comment.