From abb7e64e8926d66086e3708e237aadde4226e9eb Mon Sep 17 00:00:00 2001 From: Suzy Mueller Date: Tue, 2 Jul 2019 17:41:09 -0400 Subject: [PATCH] internal/lsp: include declaration for references A client can specify "IncludeDeclaration" in its ReferenceParams. When they do so, we want to include the declaration, even if it was not in the scope we searched for references. Additionally, we also return the location of the declaration first in the result array when it is included in the results. Updates golang/go#32572 Change-Id: I12837cd98102ee8d531f0f4bac2fb7bded2564c0 Reviewed-on: https://go-review.googlesource.com/c/tools/+/184723 Run-TryBot: Suzy Mueller TryBot-Result: Gobot Gobot Reviewed-by: Rebecca Stambler --- internal/lsp/references.go | 12 ++++++++++++ internal/lsp/source/references.go | 7 ++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/internal/lsp/references.go b/internal/lsp/references.go index 407371e8..a6506a59 100644 --- a/internal/lsp/references.go +++ b/internal/lsp/references.go @@ -36,6 +36,18 @@ func (s *Server) references(ctx context.Context, params *protocol.ReferenceParam if err != nil { view.Session().Logger().Errorf(ctx, "no references for %s: %v", ident.Name, err) } + if params.Context.IncludeDeclaration { + // The declaration of this identifier may not be in the + // scope that we search for references, so make sure + // it is added to the beginning of the list if IncludeDeclaration + // was specified. + references = append([]*source.ReferenceInfo{ + &source.ReferenceInfo{ + Range: ident.DeclarationRange(), + }, + }, references...) + } + // Get the location of each reference to return as the result. locations := make([]protocol.Location, 0, len(references)) seen := make(map[span.Span]bool) diff --git a/internal/lsp/source/references.go b/internal/lsp/source/references.go index b832e43e..cab6a21c 100644 --- a/internal/lsp/source/references.go +++ b/internal/lsp/source/references.go @@ -23,7 +23,7 @@ type ReferenceInfo struct { } // References returns a list of references for a given identifier within the packages -// containing i.File. +// containing i.File. Declarations appear first in the result. func (i *IdentifierInfo) References(ctx context.Context) ([]*ReferenceInfo, error) { var references []*ReferenceInfo @@ -57,13 +57,14 @@ func (i *IdentifierInfo) References(ctx context.Context) ([]*ReferenceInfo, erro if obj == nil || obj.Pos() != i.decl.obj.Pos() { continue } - references = append(references, &ReferenceInfo{ + // Add the declarations at the beginning of the references list. + references = append([]*ReferenceInfo{&ReferenceInfo{ Name: ident.Name, Range: span.NewRange(i.File.FileSet(), ident.Pos(), ident.End()), ident: ident, obj: obj, isDeclaration: true, - }) + }}, references...) } for ident, obj := range info.Uses { if obj == nil || obj.Pos() != i.decl.obj.Pos() {