From e491332ed8cc1fe97843bb892f55fba0bb410c5a Mon Sep 17 00:00:00 2001 From: Suzy Mueller Date: Mon, 8 Jul 2019 17:14:33 -0700 Subject: [PATCH] internal/lsp: compare names when finding references Objects for builtin types all have position token.NoPos. We do not want all objects that have position token.NoPos to be matched when we are looking for references for this object, so we need to compare the names of the objects as well. Fixes golang/go#32991 Change-Id: I67e7aba9909ebcbb246203ea5c572debf996c792 Reviewed-on: https://go-review.googlesource.com/c/tools/+/185247 Run-TryBot: Suzy Mueller TryBot-Result: Gobot Gobot Reviewed-by: Rebecca Stambler --- internal/lsp/source/references.go | 13 ++++++++++--- internal/lsp/testdata/references/refs.go | 11 +++++++++++ internal/lsp/tests/tests.go | 2 +- 3 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 internal/lsp/testdata/references/refs.go diff --git a/internal/lsp/source/references.go b/internal/lsp/source/references.go index 0b199e68..5cbb4429 100644 --- a/internal/lsp/source/references.go +++ b/internal/lsp/source/references.go @@ -56,8 +56,7 @@ func (i *IdentifierInfo) References(ctx context.Context) ([]*ReferenceInfo, erro return nil, fmt.Errorf("package %s has no types info", pkg.PkgPath()) } for ident, obj := range info.Defs { - // TODO(suzmue): support the case where an identifier may have two different declarations. - if obj == nil || obj.Pos() != i.decl.obj.Pos() { + if obj == nil || !sameObj(obj, i.decl.obj) { continue } // Add the declarations at the beginning of the references list. @@ -70,7 +69,7 @@ func (i *IdentifierInfo) References(ctx context.Context) ([]*ReferenceInfo, erro }}, references...) } for ident, obj := range info.Uses { - if obj == nil || obj.Pos() != i.decl.obj.Pos() { + if obj == nil || !sameObj(obj, i.decl.obj) { continue } references = append(references, &ReferenceInfo{ @@ -85,3 +84,11 @@ func (i *IdentifierInfo) References(ctx context.Context) ([]*ReferenceInfo, erro return references, nil } + +// sameObj returns true if obj is the same as declObj. +// Objects are the same if they have the some Pos and Name. +func sameObj(obj, declObj types.Object) bool { + // TODO(suzmue): support the case where an identifier may have two different + // declaration positions. + return obj.Pos() == declObj.Pos() && obj.Name() == declObj.Name() +} diff --git a/internal/lsp/testdata/references/refs.go b/internal/lsp/testdata/references/refs.go new file mode 100644 index 00000000..89219c2b --- /dev/null +++ b/internal/lsp/testdata/references/refs.go @@ -0,0 +1,11 @@ +package refs + +type i int //@mark(typeInt, "int"),refs("int", typeInt, argInt, returnInt) + +func _(_ int) []bool { //@mark(argInt, "int") + return nil +} + +func _(_ string) int { //@mark(returnInt, "int") + return 0 +} diff --git a/internal/lsp/tests/tests.go b/internal/lsp/tests/tests.go index 196026f4..030b2bde 100644 --- a/internal/lsp/tests/tests.go +++ b/internal/lsp/tests/tests.go @@ -33,7 +33,7 @@ const ( ExpectedDefinitionsCount = 38 ExpectedTypeDefinitionsCount = 2 ExpectedHighlightsCount = 2 - ExpectedReferencesCount = 4 + ExpectedReferencesCount = 5 ExpectedRenamesCount = 13 ExpectedSymbolsCount = 1 ExpectedSignaturesCount = 21