mirror of
https://github.com/golang/go
synced 2024-09-30 22:38:33 -06:00
internal/lsp: make interface methods children of the interface symbol
Change-Id: I8dbb1400a228ea077f63c2c48f8dba0ac93990d2 Reviewed-on: https://go-review.googlesource.com/c/tools/+/173237 Reviewed-by: Rebecca Stambler <rstambler@golang.org> Run-TryBot: Rebecca Stambler <rstambler@golang.org>
This commit is contained in:
parent
4bf14f7f06
commit
f62e16ca41
@ -68,7 +68,7 @@ func DocumentSymbols(ctx context.Context, f File) []Symbol {
|
||||
switch spec := spec.(type) {
|
||||
case *ast.TypeSpec:
|
||||
if obj := info.ObjectOf(spec.Name); obj != nil {
|
||||
ts := typeSymbol(spec, obj, fset, q)
|
||||
ts := typeSymbol(info, spec, obj, fset, q)
|
||||
symbols = append(symbols, ts)
|
||||
symbolsToReceiver[obj.Type()] = len(symbols) - 1
|
||||
}
|
||||
@ -161,7 +161,7 @@ func setKind(s *Symbol, typ types.Type, q types.Qualifier) {
|
||||
}
|
||||
}
|
||||
|
||||
func typeSymbol(spec *ast.TypeSpec, obj types.Object, fset *token.FileSet, q types.Qualifier) Symbol {
|
||||
func typeSymbol(info *types.Info, spec *ast.TypeSpec, obj types.Object, fset *token.FileSet, q types.Qualifier) Symbol {
|
||||
s := Symbol{Name: obj.Name()}
|
||||
s.Detail, _ = formatType(obj.Type(), q)
|
||||
setKind(&s, obj.Type(), q)
|
||||
@ -193,6 +193,66 @@ func typeSymbol(spec *ast.TypeSpec, obj types.Object, fset *token.FileSet, q typ
|
||||
}
|
||||
}
|
||||
|
||||
ti, objIsInterface := obj.Type().Underlying().(*types.Interface)
|
||||
ai, specIsInterface := spec.Type.(*ast.InterfaceType)
|
||||
if objIsInterface && specIsInterface {
|
||||
for i := 0; i < ti.NumExplicitMethods(); i++ {
|
||||
method := ti.ExplicitMethod(i)
|
||||
child := Symbol{
|
||||
Name: method.Name(),
|
||||
Kind: MethodSymbol,
|
||||
}
|
||||
|
||||
var spanNode, selectionNode ast.Node
|
||||
Methods:
|
||||
for _, f := range ai.Methods.List {
|
||||
for _, id := range f.Names {
|
||||
if id.Name == method.Name() {
|
||||
spanNode, selectionNode = f, id
|
||||
break Methods
|
||||
}
|
||||
}
|
||||
}
|
||||
if span, err := nodeSpan(spanNode, fset); err == nil {
|
||||
child.Span = span
|
||||
}
|
||||
if span, err := nodeSpan(selectionNode, fset); err == nil {
|
||||
child.SelectionSpan = span
|
||||
}
|
||||
s.Children = append(s.Children, child)
|
||||
}
|
||||
|
||||
for i := 0; i < ti.NumEmbeddeds(); i++ {
|
||||
embedded := ti.EmbeddedType(i)
|
||||
nt, isNamed := embedded.(*types.Named)
|
||||
if !isNamed {
|
||||
continue
|
||||
}
|
||||
|
||||
child := Symbol{Name: types.TypeString(embedded, q)}
|
||||
setKind(&child, embedded, q)
|
||||
var spanNode, selectionNode ast.Node
|
||||
Embeddeds:
|
||||
for _, f := range ai.Methods.List {
|
||||
if len(f.Names) > 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if t := info.TypeOf(f.Type); types.Identical(nt, t) {
|
||||
spanNode, selectionNode = f, f.Type
|
||||
break Embeddeds
|
||||
}
|
||||
}
|
||||
|
||||
if span, err := nodeSpan(spanNode, fset); err == nil {
|
||||
child.Span = span
|
||||
}
|
||||
if span, err := nodeSpan(selectionNode, fset); err == nil {
|
||||
child.SelectionSpan = span
|
||||
}
|
||||
s.Children = append(s.Children, child)
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
|
17
internal/lsp/testdata/symbols/main.go
vendored
17
internal/lsp/testdata/symbols/main.go
vendored
@ -1,6 +1,8 @@
|
||||
package main
|
||||
|
||||
import "io"
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
var x = 42 //@symbol("x", "x", "Variable", "")
|
||||
|
||||
@ -39,5 +41,16 @@ func main() { //@symbol("main", "main", "Function", "")
|
||||
}
|
||||
|
||||
type Stringer interface { //@symbol("Stringer", "Stringer", "Interface", "")
|
||||
String() string
|
||||
String() string //@symbol("String", "String", "Method", "Stringer")
|
||||
}
|
||||
|
||||
type ABer interface { //@symbol("ABer", "ABer", "Interface", "")
|
||||
B() //@symbol("B", "B", "Method", "ABer")
|
||||
A() string //@symbol("A", "A", "Method", "ABer")
|
||||
}
|
||||
|
||||
type WithEmbeddeds interface { //@symbol("WithEmbeddeds", "WithEmbeddeds", "Interface", "")
|
||||
Do() //@symbol("Do", "Do", "Method", "WithEmbeddeds")
|
||||
ABer //@symbol("ABer", "ABer", "Interface", "WithEmbeddeds")
|
||||
io.Writer //@symbol("io.Writer", "io.Writer", "Interface", "WithEmbeddeds")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user