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 20:20:20 +01:00
|
|
|
package registry
|
|
|
|
|
|
|
|
import (
|
|
|
|
"go/types"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Var represents a method variable/parameter.
|
|
|
|
//
|
|
|
|
// It should be created using a method scope instance.
|
|
|
|
type Var struct {
|
|
|
|
vr *types.Var
|
|
|
|
imports map[string]*Package
|
|
|
|
moqPkgPath string
|
|
|
|
|
|
|
|
Name string
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsSlice returns whether the type (or the underlying type) is a slice.
|
|
|
|
func (v Var) IsSlice() bool {
|
|
|
|
_, ok := v.vr.Type().Underlying().(*types.Slice)
|
|
|
|
return ok
|
|
|
|
}
|
|
|
|
|
|
|
|
// TypeString returns the variable type with the package qualifier in the
|
|
|
|
// format 'pkg.Type'.
|
|
|
|
func (v Var) TypeString() string {
|
|
|
|
return types.TypeString(v.vr.Type(), v.packageQualifier)
|
|
|
|
}
|
|
|
|
|
|
|
|
// packageQualifier is a types.Qualifier.
|
|
|
|
func (v Var) packageQualifier(pkg *types.Package) string {
|
|
|
|
path := stripVendorPath(pkg.Path())
|
|
|
|
if v.moqPkgPath != "" && v.moqPkgPath == path {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
return v.imports[path].Qualifier()
|
|
|
|
}
|
|
|
|
|
2021-02-14 14:10:16 +01:00
|
|
|
func varName(vr *types.Var, suffix string) string {
|
|
|
|
name := vr.Name()
|
|
|
|
if name != "" && name != "_" {
|
|
|
|
return name + suffix
|
|
|
|
}
|
|
|
|
|
|
|
|
name = varNameForType(vr.Type()) + suffix
|
|
|
|
|
|
|
|
switch name {
|
|
|
|
case "mock", "callInfo", "break", "default", "func", "interface", "select", "case", "defer", "go", "map", "struct",
|
|
|
|
"chan", "else", "goto", "package", "switch", "const", "fallthrough", "if", "range", "type", "continue", "for",
|
2021-12-18 04:26:01 +01:00
|
|
|
"import", "return", "var",
|
|
|
|
// avoid shadowing basic types
|
|
|
|
"string", "bool", "byte", "rune", "uintptr",
|
|
|
|
"int", "int8", "int16", "int32", "int64",
|
|
|
|
"uint", "uint8", "uint16", "uint32", "uint64",
|
|
|
|
"float32", "float64", "complex64", "complex128":
|
2021-02-14 14:10:16 +01:00
|
|
|
name += "MoqParam"
|
|
|
|
}
|
|
|
|
|
|
|
|
return name
|
|
|
|
}
|
|
|
|
|
|
|
|
// varNameForType generates a name for the variable using the type
|
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 20:20:20 +01:00
|
|
|
// information.
|
|
|
|
//
|
|
|
|
// Examples:
|
|
|
|
// - string -> s
|
|
|
|
// - int -> n
|
|
|
|
// - chan int -> intCh
|
|
|
|
// - []a.MyType -> myTypes
|
|
|
|
// - map[string]int -> stringToInt
|
|
|
|
// - error -> err
|
|
|
|
// - a.MyType -> myType
|
2021-02-14 14:10:16 +01:00
|
|
|
func varNameForType(t types.Type) string {
|
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 20:20:20 +01:00
|
|
|
nestedType := func(t types.Type) string {
|
|
|
|
if t, ok := t.(*types.Basic); ok {
|
|
|
|
return deCapitalise(t.String())
|
|
|
|
}
|
2021-02-14 14:10:16 +01:00
|
|
|
return varNameForType(t)
|
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 20:20:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
switch t := t.(type) {
|
|
|
|
case *types.Named:
|
|
|
|
if t.Obj().Name() == "error" {
|
|
|
|
return "err"
|
|
|
|
}
|
|
|
|
|
|
|
|
name := deCapitalise(t.Obj().Name())
|
|
|
|
if name == t.Obj().Name() {
|
|
|
|
name += "MoqParam"
|
|
|
|
}
|
|
|
|
|
|
|
|
return name
|
|
|
|
|
|
|
|
case *types.Basic:
|
|
|
|
return basicTypeVarName(t)
|
|
|
|
|
|
|
|
case *types.Array:
|
|
|
|
return nestedType(t.Elem()) + "s"
|
|
|
|
|
|
|
|
case *types.Slice:
|
|
|
|
return nestedType(t.Elem()) + "s"
|
|
|
|
|
|
|
|
case *types.Struct: // anonymous struct
|
|
|
|
return "val"
|
|
|
|
|
|
|
|
case *types.Pointer:
|
2021-02-14 14:10:16 +01:00
|
|
|
return varNameForType(t.Elem())
|
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 20:20:20 +01:00
|
|
|
|
|
|
|
case *types.Signature:
|
|
|
|
return "fn"
|
|
|
|
|
|
|
|
case *types.Interface: // anonymous interface
|
|
|
|
return "ifaceVal"
|
|
|
|
|
|
|
|
case *types.Map:
|
|
|
|
return nestedType(t.Key()) + "To" + capitalise(nestedType(t.Elem()))
|
|
|
|
|
|
|
|
case *types.Chan:
|
|
|
|
return nestedType(t.Elem()) + "Ch"
|
|
|
|
}
|
|
|
|
|
|
|
|
return "v"
|
|
|
|
}
|
|
|
|
|
|
|
|
func basicTypeVarName(b *types.Basic) string {
|
|
|
|
switch b.Info() {
|
|
|
|
case types.IsBoolean:
|
|
|
|
return "b"
|
|
|
|
|
|
|
|
case types.IsInteger:
|
|
|
|
return "n"
|
|
|
|
|
|
|
|
case types.IsFloat:
|
|
|
|
return "f"
|
|
|
|
|
|
|
|
case types.IsString:
|
|
|
|
return "s"
|
|
|
|
}
|
|
|
|
|
|
|
|
return "v"
|
|
|
|
}
|
|
|
|
|
|
|
|
func capitalise(s string) string { return strings.ToUpper(s[:1]) + s[1:] }
|
|
|
|
func deCapitalise(s string) string { return strings.ToLower(s[:1]) + s[1:] }
|