Skip to content

Commit

Permalink
Recursively check unique pkg names against existing imports
Browse files Browse the repository at this point in the history
When we generate a unique name for pkg a on conflict with pkg b, the new
name could already be in use for pkg c. So recursively check each unique
name against existing imports before setting it.
  • Loading branch information
sudo-suhas committed Nov 20, 2022
1 parent 60a16ec commit a464ccc
Show file tree
Hide file tree
Showing 10 changed files with 169 additions and 13 deletions.
38 changes: 25 additions & 13 deletions internal/registry/registry.go
Expand Up @@ -96,7 +96,7 @@ func (r *Registry) AddImport(pkg *types.Package) *Package {
imprt := Package{pkg: pkg, Alias: r.aliases[path]}

if conflict, ok := r.searchImport(imprt.Qualifier()); ok {
resolveImportConflict(&imprt, conflict, 0)
r.resolveImportConflict(&imprt, conflict, 0)
}

r.imports[path] = &imprt
Expand Down Expand Up @@ -126,6 +126,30 @@ func (r Registry) searchImport(name string) (*Package, bool) {
return nil, false
}

// resolveImportConflict generates and assigns a unique alias for
// packages with conflicting qualifiers.
func (r Registry) resolveImportConflict(a, b *Package, lvl int) {
if a.uniqueName(lvl) == b.uniqueName(lvl) {
r.resolveImportConflict(a, b, lvl+1)
return
}

for _, p := range []*Package{a, b} {
name := p.uniqueName(lvl)
// Even though the name is not conflicting with the other package we
// got, the new name we want to pick might already be taken. So check
// again for conflicts and resolve them as well. Since the name for
// this package would also get set in the recursive function call, skip
// setting the alias after it.
if conflict, ok := r.searchImport(name); ok && conflict != p {
r.resolveImportConflict(p, conflict, lvl+1)
continue
}

p.Alias = name
}
}

func pkgInfoFromPath(srcDir string, mode packages.LoadMode) (*packages.Package, error) {
pkgs, err := packages.Load(&packages.Config{
Mode: mode,
Expand Down Expand Up @@ -182,15 +206,3 @@ func parseImportsAliases(pkg *packages.Package) map[string]string {
}
return aliases
}

// resolveImportConflict generates and assigns a unique alias for
// packages with conflicting qualifiers.
func resolveImportConflict(a, b *Package, lvl int) {
u1, u2 := a.uniqueName(lvl), b.uniqueName(lvl)
if u1 != u2 {
a.Alias, b.Alias = u1, u2
return
}

resolveImportConflict(a, b, lvl+1)
}
6 changes: 6 additions & 0 deletions pkg/moq/moq_test.go
Expand Up @@ -389,6 +389,12 @@ func TestMockGolden(t *testing.T) {
interfaces: []string{"GenericStore1", "GenericStore2", "AliasStore"},
goldenFile: filepath.Join("testpackages/generics", "generics_moq.golden.go"),
},
{
name: "TransientImport",
cfg: Config{SrcDir: "testpackages/transientimport"},
interfaces: []string{"Transient"},
goldenFile: filepath.Join("testpackages/transientimport", "transient_moq.golden.go"),
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
Expand Down
13 changes: 13 additions & 0 deletions pkg/moq/testpackages/transientimport/base/type.go
@@ -0,0 +1,13 @@
package base

import (
four "github.com/matryer/moq/pkg/moq/testpackages/transientimport/four/app/v1"
one "github.com/matryer/moq/pkg/moq/testpackages/transientimport/one/v1"
"github.com/matryer/moq/pkg/moq/testpackages/transientimport/onev1"
three "github.com/matryer/moq/pkg/moq/testpackages/transientimport/three/v1"
two "github.com/matryer/moq/pkg/moq/testpackages/transientimport/two/app/v1"
)

type Transient interface {
DoSomething(onev1.Zero, one.One, two.Two, three.Three, four.Four)
}
3 changes: 3 additions & 0 deletions pkg/moq/testpackages/transientimport/four/app/v1/four.go
@@ -0,0 +1,3 @@
package v1

type Four string
3 changes: 3 additions & 0 deletions pkg/moq/testpackages/transientimport/one/v1/one.go
@@ -0,0 +1,3 @@
package v1

type One string
3 changes: 3 additions & 0 deletions pkg/moq/testpackages/transientimport/onev1/zero.go
@@ -0,0 +1,3 @@
package onev1

type Zero string
3 changes: 3 additions & 0 deletions pkg/moq/testpackages/transientimport/three/v1/three.go
@@ -0,0 +1,3 @@
package v1

type Three string
7 changes: 7 additions & 0 deletions pkg/moq/testpackages/transientimport/transient.go
@@ -0,0 +1,7 @@
package transientimport

import (
"github.com/matryer/moq/pkg/moq/testpackages/transientimport/base"
)

type Transient = base.Transient
103 changes: 103 additions & 0 deletions pkg/moq/testpackages/transientimport/transient_moq.golden.go

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

3 changes: 3 additions & 0 deletions pkg/moq/testpackages/transientimport/two/app/v1/two.go
@@ -0,0 +1,3 @@
package v1

type Two string

0 comments on commit a464ccc

Please sign in to comment.