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:
Robert Griesemer 2015-06-05 10:18:37 -07:00
parent cc54cd6553
commit 3f8eecd15b
7 changed files with 30 additions and 22 deletions

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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
} }

View File

@ -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