From 20a88df65cb9e57f5fac492ba6629232a4f89eb2 Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Thu, 9 Feb 2017 02:46:58 -0500 Subject: [PATCH] Bug 399147 - Make 'Find References' find using-declarations This is a revised approach for fixing this bug by giving using- declarations implicit names for each delegate binding. Change-Id: Ib9695c30258b8cb322ae1548ab022e357318135c --- .../internal/pdom/tests/NamespaceTests.java | 2 +- .../dom/ast/cpp/ICPPASTUsingDeclaration.java | 4 ++- .../parser/cpp/CPPASTUsingDeclaration.java | 33 +++++++++++++++++++ .../ui/tests/search/FindReferencesTest.java | 11 +++++++ .../ui/editor/SemanticHighlightings.java | 6 ++++ .../search/actions/OpenDeclarationsJob.java | 4 +-- 6 files changed, 55 insertions(+), 5 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/NamespaceTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/NamespaceTests.java index 70a6cc6ecb5..43062a9da00 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/NamespaceTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/NamespaceTests.java @@ -209,6 +209,6 @@ public class NamespaceTests extends PDOMTestBase { assertEquals(0, decls.length); IName[] refs = pdom.findNames(variable1, IIndex.FIND_REFERENCES); - assertEquals(2, refs.length); + assertEquals(3, refs.length); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTUsingDeclaration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTUsingDeclaration.java index d4998c91423..f0b4c61cad3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTUsingDeclaration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTUsingDeclaration.java @@ -14,6 +14,7 @@ package org.eclipse.cdt.core.dom.ast.cpp; import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; import org.eclipse.cdt.core.dom.ast.IASTAttributeOwner; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNameOwner; @@ -23,7 +24,8 @@ import org.eclipse.cdt.core.dom.ast.IASTNameOwner; * @noextend This interface is not intended to be extended by clients. * @noimplement This interface is not intended to be implemented by clients. */ -public interface ICPPASTUsingDeclaration extends IASTDeclaration, IASTNameOwner, IASTAttributeOwner { +public interface ICPPASTUsingDeclaration extends IASTDeclaration, IASTNameOwner, IASTAttributeOwner, + IASTImplicitNameOwner { /** * NAME is the qualified name brought into scope. */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUsingDeclaration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUsingDeclaration.java index ae51f09b34b..8eecae37292 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUsingDeclaration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUsingDeclaration.java @@ -16,17 +16,23 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import java.util.Arrays; import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.IASTImplicitName; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.ICPPASTCompletionContext; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; +import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; public class CPPASTUsingDeclaration extends CPPASTAttributeOwner implements ICPPASTUsingDeclaration, ICPPASTCompletionContext { private boolean typeName; private IASTName name; + + // The using-declaration has an implicit name referencing every delegate binding. + private IASTImplicitName[] fImplicitNames; public CPPASTUsingDeclaration() { } @@ -86,6 +92,12 @@ public class CPPASTUsingDeclaration extends CPPASTAttributeOwner if (!acceptByAttributeSpecifiers(action)) return false; if (name != null && !name.accept(action)) return false; + + if (action.shouldVisitImplicitNames) { + for (IASTImplicitName name : getImplicitNames()) { + if (!name.accept(action)) return false; + } + } if (action.shouldVisitDeclarations) { switch (action.leave(this)) { @@ -132,4 +144,25 @@ public class CPPASTUsingDeclaration extends CPPASTAttributeOwner public IBinding[] findBindings(IASTName n, boolean isPrefix) { return findBindings(n, isPrefix, null); } + + @Override + public IASTImplicitName[] getImplicitNames() { + if (fImplicitNames == null) { + fImplicitNames = IASTImplicitName.EMPTY_NAME_ARRAY; + IBinding usingDecl = name.resolveBinding(); + if (usingDecl instanceof ICPPUsingDeclaration) { + IBinding[] delegates = ((ICPPUsingDeclaration) usingDecl).getDelegates(); + if (delegates.length > 0) { + fImplicitNames = new IASTImplicitName[delegates.length]; + for (int i = 0; i < delegates.length; ++i) { + CPPASTImplicitName reference = new CPPASTImplicitName(name.getSimpleID(), this); + reference.setBinding(delegates[i]); + reference.setOffsetAndLength((ASTNode) name.getLastName()); + fImplicitNames[i] = reference; + } + } + } + } + return fImplicitNames; + } } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/search/FindReferencesTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/search/FindReferencesTest.java index 15e9b86cd56..dc5f4a3e6b6 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/search/FindReferencesTest.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/search/FindReferencesTest.java @@ -132,6 +132,17 @@ public class FindReferencesTest extends SearchTestBase { assertNotNull(matches[0].getEnclosingElement()); } + // namespace N { + // void foo(); + // } + // using N::foo; + + // // empty file + public void testUsingDeclaration_399147() throws Exception { + CSearchQuery query = makeSearchQuery(fHeaderFile, selectSection("foo", "void foo", fHeaderContents)); + assertOccurrences(query, 1); + } + // // empty file // namespace { struct A {}; } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java index 5f29508996f..1cca014c94f 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java @@ -58,6 +58,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNameSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVirtSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPAliasTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPAliasTemplateInstance; @@ -1046,6 +1047,11 @@ public class SemanticHighlightings { if (node instanceof ICPPASTQualifiedName || node instanceof ICPPASTTemplateId) { return false; } + if (node instanceof IASTImplicitName && node.getParent() instanceof ICPPASTUsingDeclaration) { + // For names in an inheriting constructor declaration, we want to use the method + // highlighting (since it's a constructor), not the class highlighting. + return false; + } if (node instanceof IASTName) { IBinding binding= token.getBinding(); if (binding instanceof ICompositeType && !(binding instanceof ICPPTemplateParameter)) { diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java index e09b34be6b9..a21940abc73 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java @@ -299,9 +299,7 @@ class OpenDeclarationsJob extends Job implements ASTRunnable { } } if (binding instanceof ICPPUsingDeclaration) { - // For using-declarations, apply the logic below to each delegate - // individually. - bindings = ArrayUtil.addAll(bindings, ((ICPPUsingDeclaration) binding).getDelegates()); + // Skip using-declaration bindings. Their delegates will be among the implicit targets. continue; } if (binding != null && !(binding instanceof IProblemBinding)) {