go/types: move MethodSetCache into package go/types/typeutil
Change-Id: Iba5d7c2df533948a5b28373b077cc0476a6745ad Reviewed-on: https://go-review.googlesource.com/10770 Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
parent
cc54cd6553
commit
3f8eecd15b
|
@ -24,7 +24,7 @@ type Program struct {
|
||||||
imported map[string]*Package // all importable Packages, keyed by import path
|
imported map[string]*Package // all importable Packages, keyed by import path
|
||||||
packages map[*types.Package]*Package // all loaded Packages, keyed by object
|
packages map[*types.Package]*Package // all loaded Packages, keyed by object
|
||||||
mode BuilderMode // set of mode bits for SSA construction
|
mode BuilderMode // set of mode bits for SSA construction
|
||||||
MethodSets types.MethodSetCache // cache of type-checker's method-sets
|
MethodSets typeutil.MethodSetCache // cache of type-checker's method-sets
|
||||||
|
|
||||||
methodsMu sync.Mutex // guards the following maps:
|
methodsMu sync.Mutex // guards the following maps:
|
||||||
methodSets typeutil.Map // maps type to its concrete methodSet
|
methodSets typeutil.Map // maps type to its concrete methodSet
|
||||||
|
|
|
@ -4,38 +4,42 @@
|
||||||
|
|
||||||
// This file implements a cache of method sets.
|
// This file implements a cache of method sets.
|
||||||
|
|
||||||
package types
|
package typeutil
|
||||||
|
|
||||||
import "sync"
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"golang.org/x/tools/go/types"
|
||||||
|
)
|
||||||
|
|
||||||
// A MethodSetCache records the method set of each type T for which
|
// A MethodSetCache records the method set of each type T for which
|
||||||
// MethodSet(T) is called so that repeat queries are fast.
|
// MethodSet(T) is called so that repeat queries are fast.
|
||||||
// The zero value is a ready-to-use cache instance.
|
// The zero value is a ready-to-use cache instance.
|
||||||
type MethodSetCache struct {
|
type MethodSetCache struct {
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
named map[*Named]struct{ value, pointer *MethodSet } // method sets for named N and *N
|
named map[*types.Named]struct{ value, pointer *types.MethodSet } // method sets for named N and *N
|
||||||
others map[Type]*MethodSet // all other types
|
others map[types.Type]*types.MethodSet // all other types
|
||||||
}
|
}
|
||||||
|
|
||||||
// MethodSet returns the method set of type T. It is thread-safe.
|
// MethodSet returns the method set of type T. It is thread-safe.
|
||||||
//
|
//
|
||||||
// If cache is nil, this function is equivalent to NewMethodSet(T).
|
// If cache is nil, this function is equivalent to types.NewMethodSet(T).
|
||||||
// Utility functions can thus expose an optional *MethodSetCache
|
// Utility functions can thus expose an optional *MethodSetCache
|
||||||
// parameter to clients that care about performance.
|
// parameter to clients that care about performance.
|
||||||
//
|
//
|
||||||
func (cache *MethodSetCache) MethodSet(T Type) *MethodSet {
|
func (cache *MethodSetCache) MethodSet(T types.Type) *types.MethodSet {
|
||||||
if cache == nil {
|
if cache == nil {
|
||||||
return NewMethodSet(T)
|
return types.NewMethodSet(T)
|
||||||
}
|
}
|
||||||
cache.mu.Lock()
|
cache.mu.Lock()
|
||||||
defer cache.mu.Unlock()
|
defer cache.mu.Unlock()
|
||||||
|
|
||||||
switch T := T.(type) {
|
switch T := T.(type) {
|
||||||
case *Named:
|
case *types.Named:
|
||||||
return cache.lookupNamed(T).value
|
return cache.lookupNamed(T).value
|
||||||
|
|
||||||
case *Pointer:
|
case *types.Pointer:
|
||||||
if N, ok := T.Elem().(*Named); ok {
|
if N, ok := T.Elem().(*types.Named); ok {
|
||||||
return cache.lookupNamed(N).pointer
|
return cache.lookupNamed(N).pointer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,25 +48,25 @@ func (cache *MethodSetCache) MethodSet(T Type) *MethodSet {
|
||||||
// (The map uses pointer equivalence, not type identity.)
|
// (The map uses pointer equivalence, not type identity.)
|
||||||
mset := cache.others[T]
|
mset := cache.others[T]
|
||||||
if mset == nil {
|
if mset == nil {
|
||||||
mset = NewMethodSet(T)
|
mset = types.NewMethodSet(T)
|
||||||
if cache.others == nil {
|
if cache.others == nil {
|
||||||
cache.others = make(map[Type]*MethodSet)
|
cache.others = make(map[types.Type]*types.MethodSet)
|
||||||
}
|
}
|
||||||
cache.others[T] = mset
|
cache.others[T] = mset
|
||||||
}
|
}
|
||||||
return mset
|
return mset
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cache *MethodSetCache) lookupNamed(named *Named) struct{ value, pointer *MethodSet } {
|
func (cache *MethodSetCache) lookupNamed(named *types.Named) struct{ value, pointer *types.MethodSet } {
|
||||||
if cache.named == nil {
|
if cache.named == nil {
|
||||||
cache.named = make(map[*Named]struct{ value, pointer *MethodSet })
|
cache.named = make(map[*types.Named]struct{ value, pointer *types.MethodSet })
|
||||||
}
|
}
|
||||||
// Avoid recomputing mset(*T) for each distinct Pointer
|
// Avoid recomputing mset(*T) for each distinct Pointer
|
||||||
// instance whose underlying type is a named type.
|
// instance whose underlying type is a named type.
|
||||||
msets, ok := cache.named[named]
|
msets, ok := cache.named[named]
|
||||||
if !ok {
|
if !ok {
|
||||||
msets.value = NewMethodSet(named)
|
msets.value = types.NewMethodSet(named)
|
||||||
msets.pointer = NewMethodSet(NewPointer(named))
|
msets.pointer = types.NewMethodSet(types.NewPointer(named))
|
||||||
cache.named[named] = msets
|
cache.named[named] = msets
|
||||||
}
|
}
|
||||||
return msets
|
return msets
|
|
@ -17,7 +17,7 @@ import "golang.org/x/tools/go/types"
|
||||||
//
|
//
|
||||||
// The order of the result is as for types.MethodSet(T).
|
// The order of the result is as for types.MethodSet(T).
|
||||||
//
|
//
|
||||||
func IntuitiveMethodSet(T types.Type, msets *types.MethodSetCache) []*types.Selection {
|
func IntuitiveMethodSet(T types.Type, msets *MethodSetCache) []*types.Selection {
|
||||||
var result []*types.Selection
|
var result []*types.Selection
|
||||||
mset := msets.MethodSet(T)
|
mset := msets.MethodSet(T)
|
||||||
if _, ok := T.Underlying().(*types.Interface); ok {
|
if _, ok := T.Underlying().(*types.Interface); ok {
|
||||||
|
|
|
@ -14,11 +14,12 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"golang.org/x/tools/go/types"
|
"golang.org/x/tools/go/types"
|
||||||
|
"golang.org/x/tools/go/types/typeutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
// computeImplements computes the "implements" relation over all pairs
|
// computeImplements computes the "implements" relation over all pairs
|
||||||
// of named types in allNamed.
|
// of named types in allNamed.
|
||||||
func computeImplements(cache *types.MethodSetCache, allNamed []*types.Named) map[*types.Named]implementsFacts {
|
func computeImplements(cache *typeutil.MethodSetCache, allNamed []*types.Named) map[*types.Named]implementsFacts {
|
||||||
// Information about a single type's method set.
|
// Information about a single type's method set.
|
||||||
type msetInfo struct {
|
type msetInfo struct {
|
||||||
typ types.Type
|
typ types.Type
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
|
|
||||||
"golang.org/x/tools/go/loader"
|
"golang.org/x/tools/go/loader"
|
||||||
"golang.org/x/tools/go/types"
|
"golang.org/x/tools/go/types"
|
||||||
|
"golang.org/x/tools/go/types/typeutil"
|
||||||
"golang.org/x/tools/oracle/serial"
|
"golang.org/x/tools/oracle/serial"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -85,7 +86,7 @@ func implements(q *Query) error {
|
||||||
}
|
}
|
||||||
allNamed = append(allNamed, types.Universe.Lookup("error").Type())
|
allNamed = append(allNamed, types.Universe.Lookup("error").Type())
|
||||||
|
|
||||||
var msets types.MethodSetCache
|
var msets typeutil.MethodSetCache
|
||||||
|
|
||||||
// Test each named type.
|
// Test each named type.
|
||||||
var to, from, fromPtr []types.Type
|
var to, from, fromPtr []types.Type
|
||||||
|
|
|
@ -25,6 +25,7 @@ import (
|
||||||
|
|
||||||
"golang.org/x/tools/go/loader"
|
"golang.org/x/tools/go/loader"
|
||||||
"golang.org/x/tools/go/types"
|
"golang.org/x/tools/go/types"
|
||||||
|
"golang.org/x/tools/go/types/typeutil"
|
||||||
"golang.org/x/tools/refactor/importgraph"
|
"golang.org/x/tools/refactor/importgraph"
|
||||||
"golang.org/x/tools/refactor/satisfy"
|
"golang.org/x/tools/refactor/satisfy"
|
||||||
)
|
)
|
||||||
|
@ -154,7 +155,7 @@ type renamer struct {
|
||||||
to string
|
to string
|
||||||
satisfyConstraints map[satisfy.Constraint]bool
|
satisfyConstraints map[satisfy.Constraint]bool
|
||||||
packages map[*types.Package]*loader.PackageInfo // subset of iprog.AllPackages to inspect
|
packages map[*types.Package]*loader.PackageInfo // subset of iprog.AllPackages to inspect
|
||||||
msets types.MethodSetCache
|
msets typeutil.MethodSetCache
|
||||||
changeMethods bool
|
changeMethods bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@ import (
|
||||||
|
|
||||||
"golang.org/x/tools/go/ast/astutil"
|
"golang.org/x/tools/go/ast/astutil"
|
||||||
"golang.org/x/tools/go/types"
|
"golang.org/x/tools/go/types"
|
||||||
|
"golang.org/x/tools/go/types/typeutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A Constraint records the fact that the RHS type does and must
|
// A Constraint records the fact that the RHS type does and must
|
||||||
|
@ -71,7 +72,7 @@ type Constraint struct {
|
||||||
//
|
//
|
||||||
type Finder struct {
|
type Finder struct {
|
||||||
Result map[Constraint]bool
|
Result map[Constraint]bool
|
||||||
msetcache types.MethodSetCache
|
msetcache typeutil.MethodSetCache
|
||||||
|
|
||||||
// per-Find state
|
// per-Find state
|
||||||
info *types.Info
|
info *types.Info
|
||||||
|
|
Loading…
Reference in New Issue