vendor tsgo
This commit is contained in:
154
tools/tsgo/vendor/github.com/matryer/moq/internal/registry/method_scope.go
generated
vendored
Normal file
154
tools/tsgo/vendor/github.com/matryer/moq/internal/registry/method_scope.go
generated
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
package registry
|
||||
|
||||
import (
|
||||
"go/types"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// MethodScope is the sub-registry for allocating variables present in
|
||||
// the method scope.
|
||||
//
|
||||
// It should be created using a registry instance.
|
||||
type MethodScope struct {
|
||||
registry *Registry
|
||||
moqPkgPath string
|
||||
|
||||
vars []*Var
|
||||
conflicted map[string]bool
|
||||
}
|
||||
|
||||
// AddVar allocates a variable instance and adds it to the method scope.
|
||||
//
|
||||
// Variables names are generated if required and are ensured to be
|
||||
// without conflict with other variables and imported packages. It also
|
||||
// adds the relevant imports to the registry for each added variable.
|
||||
func (m *MethodScope) AddVar(vr *types.Var, suffix string) *Var {
|
||||
imports := make(map[string]*Package)
|
||||
m.populateImports(vr.Type(), imports)
|
||||
m.resolveImportVarConflicts(imports)
|
||||
|
||||
name := varName(vr, suffix)
|
||||
// Ensure that the var name does not conflict with a package import.
|
||||
if _, ok := m.registry.searchImport(name); ok {
|
||||
name += "MoqParam"
|
||||
}
|
||||
if _, ok := m.searchVar(name); ok || m.conflicted[name] {
|
||||
name = m.resolveVarNameConflict(name)
|
||||
}
|
||||
|
||||
v := Var{
|
||||
vr: vr,
|
||||
imports: imports,
|
||||
moqPkgPath: m.moqPkgPath,
|
||||
Name: name,
|
||||
}
|
||||
m.vars = append(m.vars, &v)
|
||||
return &v
|
||||
}
|
||||
|
||||
func (m *MethodScope) resolveVarNameConflict(suggested string) string {
|
||||
for n := 1; ; n++ {
|
||||
_, ok := m.searchVar(suggested + strconv.Itoa(n))
|
||||
if ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if n == 1 {
|
||||
conflict, _ := m.searchVar(suggested)
|
||||
conflict.Name += "1"
|
||||
m.conflicted[suggested] = true
|
||||
n++
|
||||
}
|
||||
return suggested + strconv.Itoa(n)
|
||||
}
|
||||
}
|
||||
|
||||
func (m MethodScope) searchVar(name string) (*Var, bool) {
|
||||
for _, v := range m.vars {
|
||||
if v.Name == name {
|
||||
return v, true
|
||||
}
|
||||
}
|
||||
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// populateImports extracts all the package imports for a given type
|
||||
// recursively. The imported packages by a single type can be more than
|
||||
// one (ex: map[a.Type]b.Type).
|
||||
func (m MethodScope) populateImports(t types.Type, imports map[string]*Package) {
|
||||
switch t := t.(type) {
|
||||
case *types.Named:
|
||||
if pkg := t.Obj().Pkg(); pkg != nil {
|
||||
imports[stripVendorPath(pkg.Path())] = m.registry.AddImport(pkg)
|
||||
}
|
||||
// The imports of a Type with a TypeList must be added to the imports list
|
||||
// For example: Foo[otherpackage.Bar] , must have otherpackage imported
|
||||
if targs := t.TypeArgs(); targs != nil {
|
||||
for i := 0; i < targs.Len(); i++ {
|
||||
m.populateImports(targs.At(i), imports)
|
||||
}
|
||||
}
|
||||
|
||||
case *types.Alias:
|
||||
if pkg := t.Obj().Pkg(); pkg != nil {
|
||||
imports[stripVendorPath(pkg.Path())] = m.registry.AddImport(pkg)
|
||||
}
|
||||
// The imports of a Type with a TypeList must be added to the imports list
|
||||
// For example: Foo[otherpackage.Bar] , must have otherpackage imported
|
||||
if targs := t.TypeArgs(); targs != nil {
|
||||
for i := 0; i < targs.Len(); i++ {
|
||||
m.populateImports(targs.At(i), imports)
|
||||
}
|
||||
}
|
||||
|
||||
case *types.Array:
|
||||
m.populateImports(t.Elem(), imports)
|
||||
|
||||
case *types.Slice:
|
||||
m.populateImports(t.Elem(), imports)
|
||||
|
||||
case *types.Signature:
|
||||
for i := 0; i < t.Params().Len(); i++ {
|
||||
m.populateImports(t.Params().At(i).Type(), imports)
|
||||
}
|
||||
for i := 0; i < t.Results().Len(); i++ {
|
||||
m.populateImports(t.Results().At(i).Type(), imports)
|
||||
}
|
||||
|
||||
case *types.Map:
|
||||
m.populateImports(t.Key(), imports)
|
||||
m.populateImports(t.Elem(), imports)
|
||||
|
||||
case *types.Chan:
|
||||
m.populateImports(t.Elem(), imports)
|
||||
|
||||
case *types.Pointer:
|
||||
m.populateImports(t.Elem(), imports)
|
||||
|
||||
case *types.Struct: // anonymous struct
|
||||
for i := 0; i < t.NumFields(); i++ {
|
||||
m.populateImports(t.Field(i).Type(), imports)
|
||||
}
|
||||
|
||||
case *types.Interface: // anonymous interface
|
||||
for i := 0; i < t.NumExplicitMethods(); i++ {
|
||||
m.populateImports(t.ExplicitMethod(i).Type(), imports)
|
||||
}
|
||||
for i := 0; i < t.NumEmbeddeds(); i++ {
|
||||
m.populateImports(t.EmbeddedType(i), imports)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// resolveImportVarConflicts ensures that all the newly added imports do not
|
||||
// conflict with any of the existing vars.
|
||||
func (m MethodScope) resolveImportVarConflicts(imports map[string]*Package) {
|
||||
// Ensure that all the newly added imports do not conflict with any of the
|
||||
// existing vars.
|
||||
for _, imprt := range imports {
|
||||
if v, ok := m.searchVar(imprt.Qualifier()); ok {
|
||||
v.Name += "MoqParam"
|
||||
}
|
||||
}
|
||||
}
|
||||
93
tools/tsgo/vendor/github.com/matryer/moq/internal/registry/package.go
generated
vendored
Normal file
93
tools/tsgo/vendor/github.com/matryer/moq/internal/registry/package.go
generated
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
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]
|
||||
}
|
||||
}
|
||||
211
tools/tsgo/vendor/github.com/matryer/moq/internal/registry/registry.go
generated
vendored
Normal file
211
tools/tsgo/vendor/github.com/matryer/moq/internal/registry/registry.go
generated
vendored
Normal file
@@ -0,0 +1,211 @@
|
||||
package registry
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/types"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/tools/go/packages"
|
||||
)
|
||||
|
||||
// Registry encapsulates types information for the source and mock
|
||||
// destination package. For the mock package, it tracks the list of
|
||||
// imports and ensures there are no conflicts in the imported package
|
||||
// qualifiers.
|
||||
type Registry struct {
|
||||
srcPkgName string
|
||||
srcPkgTypes *types.Package
|
||||
moqPkgPath string
|
||||
aliases map[string]string
|
||||
imports map[string]*Package
|
||||
}
|
||||
|
||||
// New loads the source package info and returns a new instance of
|
||||
// Registry.
|
||||
func New(srcDir, moqPkg string) (*Registry, error) {
|
||||
srcPkg, err := pkgInfoFromPath(
|
||||
srcDir, packages.NeedName|packages.NeedSyntax|packages.NeedTypes,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't load source package: %s", err)
|
||||
}
|
||||
|
||||
return &Registry{
|
||||
srcPkgName: srcPkg.Name,
|
||||
srcPkgTypes: srcPkg.Types,
|
||||
moqPkgPath: findPkgPath(moqPkg, srcPkg.PkgPath),
|
||||
aliases: parseImportsAliases(srcPkg.Syntax),
|
||||
imports: make(map[string]*Package),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SrcPkg returns the types info for the source package.
|
||||
func (r Registry) SrcPkg() *types.Package {
|
||||
return r.srcPkgTypes
|
||||
}
|
||||
|
||||
// SrcPkgName returns the name of the source package.
|
||||
func (r Registry) SrcPkgName() string {
|
||||
return r.srcPkgName
|
||||
}
|
||||
|
||||
// LookupInterface returns the underlying interface definition of the
|
||||
// given interface name.
|
||||
func (r Registry) LookupInterface(name string) (*types.Interface, *types.TypeParamList, error) {
|
||||
obj := r.SrcPkg().Scope().Lookup(name)
|
||||
if obj == nil {
|
||||
return nil, nil, fmt.Errorf("interface not found: %s", name)
|
||||
}
|
||||
|
||||
if !types.IsInterface(obj.Type()) {
|
||||
return nil, nil, fmt.Errorf("%s (%s) is not an interface", name, obj.Type())
|
||||
}
|
||||
|
||||
var tparams *types.TypeParamList
|
||||
named, ok := obj.Type().(*types.Named)
|
||||
if ok {
|
||||
tparams = named.TypeParams()
|
||||
}
|
||||
|
||||
return obj.Type().Underlying().(*types.Interface).Complete(), tparams, nil
|
||||
}
|
||||
|
||||
// MethodScope returns a new MethodScope.
|
||||
func (r *Registry) MethodScope() *MethodScope {
|
||||
return &MethodScope{
|
||||
registry: r,
|
||||
moqPkgPath: r.moqPkgPath,
|
||||
conflicted: map[string]bool{},
|
||||
}
|
||||
}
|
||||
|
||||
// AddImport adds the given package to the set of imports. It generates a
|
||||
// suitable alias if there are any conflicts with previously imported
|
||||
// packages.
|
||||
func (r *Registry) AddImport(pkg *types.Package) *Package {
|
||||
path := stripVendorPath(pkg.Path())
|
||||
if path == r.moqPkgPath {
|
||||
return nil
|
||||
}
|
||||
|
||||
if imprt, ok := r.imports[path]; ok {
|
||||
return imprt
|
||||
}
|
||||
|
||||
imprt := Package{pkg: pkg, Alias: r.aliases[path]}
|
||||
|
||||
if conflict, ok := r.searchImport(imprt.Qualifier()); ok {
|
||||
r.resolveImportConflict(&imprt, conflict, 0)
|
||||
}
|
||||
|
||||
r.imports[path] = &imprt
|
||||
return &imprt
|
||||
}
|
||||
|
||||
// Imports returns the list of imported packages. The list is sorted by
|
||||
// path.
|
||||
func (r Registry) Imports() []*Package {
|
||||
imports := make([]*Package, 0, len(r.imports))
|
||||
for _, imprt := range r.imports {
|
||||
imports = append(imports, imprt)
|
||||
}
|
||||
sort.Slice(imports, func(i, j int) bool {
|
||||
return imports[i].Path() < imports[j].Path()
|
||||
})
|
||||
return imports
|
||||
}
|
||||
|
||||
func (r Registry) searchImport(name string) (*Package, bool) {
|
||||
for _, imprt := range r.imports {
|
||||
if imprt.Qualifier() == name {
|
||||
return imprt, true
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
Dir: srcDir,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(pkgs) == 0 {
|
||||
return nil, errors.New("package not found")
|
||||
}
|
||||
if len(pkgs) > 1 {
|
||||
return nil, errors.New("found more than one package")
|
||||
}
|
||||
if errs := pkgs[0].Errors; len(errs) != 0 {
|
||||
if len(errs) == 1 {
|
||||
return nil, errs[0]
|
||||
}
|
||||
return nil, fmt.Errorf("%s (and %d more errors)", errs[0], len(errs)-1)
|
||||
}
|
||||
return pkgs[0], nil
|
||||
}
|
||||
|
||||
func findPkgPath(pkgInputVal string, srcPkgPath string) string {
|
||||
if pkgInputVal == "" {
|
||||
return srcPkgPath
|
||||
}
|
||||
if pkgInDir(srcPkgPath, pkgInputVal) {
|
||||
return srcPkgPath
|
||||
}
|
||||
subdirectoryPath := filepath.Join(srcPkgPath, pkgInputVal)
|
||||
if pkgInDir(subdirectoryPath, pkgInputVal) {
|
||||
return subdirectoryPath
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func pkgInDir(pkgName, dir string) bool {
|
||||
currentPkg, err := pkgInfoFromPath(dir, packages.NeedName)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return currentPkg.Name == pkgName || currentPkg.Name+"_test" == pkgName
|
||||
}
|
||||
|
||||
func parseImportsAliases(syntaxTree []*ast.File) map[string]string {
|
||||
aliases := make(map[string]string)
|
||||
for _, syntax := range syntaxTree {
|
||||
for _, imprt := range syntax.Imports {
|
||||
if imprt.Name != nil && imprt.Name.Name != "." && imprt.Name.Name != "_" {
|
||||
aliases[strings.Trim(imprt.Path.Value, `"`)] = imprt.Name.Name
|
||||
}
|
||||
}
|
||||
}
|
||||
return aliases
|
||||
}
|
||||
146
tools/tsgo/vendor/github.com/matryer/moq/internal/registry/var.go
generated
vendored
Normal file
146
tools/tsgo/vendor/github.com/matryer/moq/internal/registry/var.go
generated
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
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()
|
||||
}
|
||||
|
||||
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",
|
||||
"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":
|
||||
name += "MoqParam"
|
||||
}
|
||||
|
||||
return name
|
||||
}
|
||||
|
||||
// varNameForType generates a name for the variable using the type
|
||||
// information.
|
||||
//
|
||||
// Examples:
|
||||
// - string -> s
|
||||
// - int -> n
|
||||
// - chan int -> intCh
|
||||
// - []a.MyType -> myTypes
|
||||
// - map[string]int -> stringToInt
|
||||
// - error -> err
|
||||
// - a.MyType -> myType
|
||||
func varNameForType(t types.Type) string {
|
||||
nestedType := func(t types.Type) string {
|
||||
if t, ok := t.(*types.Basic); ok {
|
||||
return deCapitalise(t.String())
|
||||
}
|
||||
return varNameForType(t)
|
||||
}
|
||||
|
||||
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:
|
||||
return varNameForType(t.Elem())
|
||||
|
||||
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:] }
|
||||
Reference in New Issue
Block a user