moq/internal/registry/package.go
Suhas Karanth 2ae606f132
Internal registry for disambiguated imports, vars (#141)
* Internal registry for disambiguated imports, vars
- Move functionality in the moq package partially into
  internal/{registry,template}.
- Leverage registry to assign unique package and variable/method
  parameter names. Use import aliases if present in interface source
  package.
BREAKING CHANGE: When the interface definition does not mention the
parameter names, the field names in call info anonymous struct will be
different.
The new field names are generated using the type info (string -> s,
int -> n, chan int -> intCh, []MyType -> myTypes, map[string]int ->
stringToInt etc.).
For example, for a string parameter previously if the field name was
'In1', the new field could be 'S' or 'S1' (depends on number of
string method parameters).
* Refactor golden file tests to be table-driven
* Fix sync pkg alias handling for moq generation
* Improve, add tests (increase coverage)
* Use $.Foo in template, avoid declaring variables
$ is set to the data argument passed to Execute, that is, to the
starting value of dot.
Variables were declared to be able to refer to the parent context.
* Consistent template field formatting
* Use tabs in generated Godoc comments' example code
* Minor simplification
* go generate
* Fix conflict for generated param name of pointer type

Excellent work by @sudo-suhas.
2021-02-01 19:20:20 +00:00

94 lines
1.8 KiB
Go

package registry
import (
"go/types"
"path"
"strings"
)
// Package represents an imported package.
type Package struct {
pkg *types.Package
Alias string
}
// NewPackage creates a new instance of Package.
func NewPackage(pkg *types.Package) *Package { return &Package{pkg: pkg} }
// Qualifier returns the qualifier which must be used to refer to types
// declared in the package.
func (p *Package) Qualifier() string {
if p == nil {
return ""
}
if p.Alias != "" {
return p.Alias
}
return p.pkg.Name()
}
// Path is the full package import path (without vendor).
func (p *Package) Path() string {
if p == nil {
return ""
}
return stripVendorPath(p.pkg.Path())
}
var replacer = strings.NewReplacer(
"go-", "",
"-go", "",
"-", "",
"_", "",
".", "",
"@", "",
"+", "",
"~", "",
)
// uniqueName generates a unique name for a package by concatenating
// path components. The generated name is guaranteed to unique with an
// appropriate level because the full package import paths themselves
// are unique.
func (p Package) uniqueName(lvl int) string {
pp := strings.Split(p.Path(), "/")
reverse(pp)
var name string
for i := 0; i < min(len(pp), lvl+1); i++ {
name = strings.ToLower(replacer.Replace(pp[i])) + name
}
return name
}
// stripVendorPath strips the vendor dir prefix from a package path.
// For example we might encounter an absolute path like
// github.com/foo/bar/vendor/github.com/pkg/errors which is resolved
// to github.com/pkg/errors.
func stripVendorPath(p string) string {
parts := strings.Split(p, "/vendor/")
if len(parts) == 1 {
return p
}
return strings.TrimLeft(path.Join(parts[1:]...), "/")
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
func reverse(a []string) {
for i := len(a)/2 - 1; i >= 0; i-- {
opp := len(a) - 1 - i
a[i], a[opp] = a[opp], a[i]
}
}