internal/lsp: trim down implementations code

Remove the unused code that was tracking concrete-type =>
interface-type mappings. It isn't clear if there is a good spot for
this in LSP.

I also made it skip interface types when looking for implementations.
It doesn't seem useful to be shown other interface types/methods when
you are looking for implementations of a given interface type/method.

Change-Id: Ib59fb717e5c1a181cc713581a22e60ed654b918c
Reviewed-on: https://go-review.googlesource.com/c/tools/+/210279
Run-TryBot: Muir Manders <muir@mnd.rs>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
This commit is contained in:
Muir Manders 2019-12-05 21:14:00 -08:00 committed by Rebecca Stambler
parent 259af5ff87
commit 9a30a9a96c
3 changed files with 17 additions and 49 deletions

View File

@ -120,68 +120,38 @@ func (i *IdentifierInfo) implementations(ctx context.Context) (implementsResult,
T = i.Type.Object.Type()
}
// Find all named types, even local types (which can have
// methods due to promotion) and the built-in "error".
// We ignore aliases 'type M = N' to avoid duplicate
// reporting of the Named type N.
// Find all named types, even local types (which can have methods
// due to promotion). We ignore aliases 'type M = N' to avoid
// duplicate reporting of the Named type N.
var allNamed []*types.Named
pkgs := map[*types.Named]Package{}
for _, pkg := range i.Snapshot.KnownPackages(ctx) {
info := pkg.GetTypesInfo()
for _, obj := range info.Defs {
if obj, ok := obj.(*types.TypeName); ok && !obj.IsAlias() {
if named, ok := obj.Type().(*types.Named); ok {
if named, ok := obj.Type().(*types.Named); ok && !isInterface(named) {
allNamed = append(allNamed, named)
pkgs[named] = pkg
}
}
}
}
allNamed = append(allNamed, types.Universe.Lookup("error").Type().(*types.Named))
var msets typeutil.MethodSetCache
// TODO(matloob): We only use the to and toMethod result for now. Figure out if we want to
// surface the from and fromPtr results to users.
// Test each named type.
var to, from, fromPtr []types.Type
var to []types.Type
for _, U := range allNamed {
if isInterface(T) {
if msets.MethodSet(T).Len() == 0 {
continue // empty interface
}
if isInterface(U) {
if msets.MethodSet(U).Len() == 0 {
continue // empty interface
}
// T interface, U interface
if !types.Identical(T, U) {
if types.AssignableTo(U, T) {
to = append(to, U)
}
if types.AssignableTo(T, U) {
from = append(from, U)
}
}
} else {
// T interface, U concrete
if types.AssignableTo(U, T) {
to = append(to, U)
} else if pU := types.NewPointer(U); types.AssignableTo(pU, T) {
to = append(to, pU)
}
}
} else if isInterface(U) {
if msets.MethodSet(U).Len() == 0 {
continue // empty interface
}
// T concrete, U interface
if types.AssignableTo(T, U) {
from = append(from, U)
} else if pT := types.NewPointer(T); types.AssignableTo(pT, U) {
fromPtr = append(fromPtr, U)
// T interface, U concrete
if types.AssignableTo(U, T) {
to = append(to, U)
} else if pU := types.NewPointer(U); types.AssignableTo(pU, T) {
to = append(to, pU)
}
}
}
@ -192,14 +162,12 @@ func (i *IdentifierInfo) implementations(ctx context.Context) (implementsResult,
types.NewMethodSet(t).Lookup(method.Pkg(), method.Name()))
}
}
return implementsResult{pkgs, to, from, fromPtr, toMethod}, nil
return implementsResult{pkgs, to, toMethod}, nil
}
// implementsResult contains the results of an implements query.
type implementsResult struct {
pkgs map[*types.Named]Package
to []types.Type // named or ptr-to-named types assignable to interface T
from []types.Type // named interfaces assignable from T
fromPtr []types.Type // named interfaces assignable only from *T
toMethod []*types.Selection
}

View File

@ -12,12 +12,12 @@ type ImpS struct{} //@ImpS
func (ImpS) Laugh() { //@mark(LaughS, "Laugh")
}
type ImpI interface { //@ImpI
Laugh() //@mark(LaughI, "Laugh"),implementations("Laugh", LaughP, OtherLaughP, LaughS, LaughL, OtherLaughI, OtherLaughS)
type ImpI interface {
Laugh() //@implementations("Laugh", LaughP, OtherLaughP, LaughS, OtherLaughS)
}
type Laugher interface { //@implementations("Laugher", ImpP, OtherImpP, ImpI, ImpS, OtherImpI, OtherImpS)
Laugh() //@mark(LaughL, "Laugh"),implementations("Laugh", LaughP, OtherLaughP, LaughI, LaughS, OtherLaughI, OtherLaughS)
type Laugher interface { //@implementations("Laugher", ImpP, OtherImpP, ImpS, OtherImpS)
Laugh() //@implementations("Laugh", LaughP, OtherLaughP, LaughS, OtherLaughS)
}
type Foo struct {

View File

@ -10,8 +10,8 @@ type ImpS struct{} //@mark(OtherImpS, "ImpS")
func (ImpS) Laugh() { //@mark(OtherLaughS, "Laugh")
}
type ImpI interface { //@mark(OtherImpI, "ImpI")
Laugh() //@mark(OtherLaughI, "Laugh")
type ImpI interface {
Laugh()
}
type Foo struct {