mirror of
https://github.com/golang/go
synced 2024-10-01 05:38:32 -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) {
|
switch spec := spec.(type) {
|
||||||
case *ast.TypeSpec:
|
case *ast.TypeSpec:
|
||||||
if obj := info.ObjectOf(spec.Name); obj != nil {
|
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)
|
symbols = append(symbols, ts)
|
||||||
symbolsToReceiver[obj.Type()] = len(symbols) - 1
|
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 := Symbol{Name: obj.Name()}
|
||||||
s.Detail, _ = formatType(obj.Type(), q)
|
s.Detail, _ = formatType(obj.Type(), q)
|
||||||
setKind(&s, 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
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
17
internal/lsp/testdata/symbols/main.go
vendored
17
internal/lsp/testdata/symbols/main.go
vendored
@ -1,6 +1,8 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "io"
|
import (
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
var x = 42 //@symbol("x", "x", "Variable", "")
|
var x = 42 //@symbol("x", "x", "Variable", "")
|
||||||
|
|
||||||
@ -39,5 +41,16 @@ func main() { //@symbol("main", "main", "Function", "")
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Stringer interface { //@symbol("Stringer", "Stringer", "Interface", "")
|
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