1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-22 22:22:11 +02:00

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
This commit is contained in:
Nathan Ridge 2017-02-09 02:46:58 -05:00
parent e7c64e785b
commit 20a88df65c
6 changed files with 55 additions and 5 deletions

View file

@ -209,6 +209,6 @@ public class NamespaceTests extends PDOMTestBase {
assertEquals(0, decls.length); assertEquals(0, decls.length);
IName[] refs = pdom.findNames(variable1, IIndex.FIND_REFERENCES); IName[] refs = pdom.findNames(variable1, IIndex.FIND_REFERENCES);
assertEquals(2, refs.length); assertEquals(3, refs.length);
} }
} }

View file

@ -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.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.IASTAttributeOwner; import org.eclipse.cdt.core.dom.ast.IASTAttributeOwner;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration; 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.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNameOwner; 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. * @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented 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 {
/** /**
* <code>NAME</code> is the qualified name brought into scope. * <code>NAME</code> is the qualified name brought into scope.
*/ */

View file

@ -16,17 +16,23 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import java.util.Arrays; import java.util.Arrays;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; 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.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICPPASTCompletionContext; 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.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; 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; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
public class CPPASTUsingDeclaration extends CPPASTAttributeOwner public class CPPASTUsingDeclaration extends CPPASTAttributeOwner
implements ICPPASTUsingDeclaration, ICPPASTCompletionContext { implements ICPPASTUsingDeclaration, ICPPASTCompletionContext {
private boolean typeName; private boolean typeName;
private IASTName name; private IASTName name;
// The using-declaration has an implicit name referencing every delegate binding.
private IASTImplicitName[] fImplicitNames;
public CPPASTUsingDeclaration() { public CPPASTUsingDeclaration() {
} }
@ -86,6 +92,12 @@ public class CPPASTUsingDeclaration extends CPPASTAttributeOwner
if (!acceptByAttributeSpecifiers(action)) return false; if (!acceptByAttributeSpecifiers(action)) return false;
if (name != null && !name.accept(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) { if (action.shouldVisitDeclarations) {
switch (action.leave(this)) { switch (action.leave(this)) {
@ -132,4 +144,25 @@ public class CPPASTUsingDeclaration extends CPPASTAttributeOwner
public IBinding[] findBindings(IASTName n, boolean isPrefix) { public IBinding[] findBindings(IASTName n, boolean isPrefix) {
return findBindings(n, isPrefix, null); 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;
}
} }

View file

@ -132,6 +132,17 @@ public class FindReferencesTest extends SearchTestBase {
assertNotNull(matches[0].getEnclosingElement()); 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 // // empty file
// namespace { struct A {}; } // namespace { struct A {}; }

View file

@ -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.ICPPASTNameSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; 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.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.ICPPASTVirtSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPAliasTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPAliasTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPAliasTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPAliasTemplateInstance;
@ -1046,6 +1047,11 @@ public class SemanticHighlightings {
if (node instanceof ICPPASTQualifiedName || node instanceof ICPPASTTemplateId) { if (node instanceof ICPPASTQualifiedName || node instanceof ICPPASTTemplateId) {
return false; 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) { if (node instanceof IASTName) {
IBinding binding= token.getBinding(); IBinding binding= token.getBinding();
if (binding instanceof ICompositeType && !(binding instanceof ICPPTemplateParameter)) { if (binding instanceof ICompositeType && !(binding instanceof ICPPTemplateParameter)) {

View file

@ -299,9 +299,7 @@ class OpenDeclarationsJob extends Job implements ASTRunnable {
} }
} }
if (binding instanceof ICPPUsingDeclaration) { if (binding instanceof ICPPUsingDeclaration) {
// For using-declarations, apply the logic below to each delegate // Skip using-declaration bindings. Their delegates will be among the implicit targets.
// individually.
bindings = ArrayUtil.addAll(bindings, ((ICPPUsingDeclaration) binding).getDelegates());
continue; continue;
} }
if (binding != null && !(binding instanceof IProblemBinding)) { if (binding != null && !(binding instanceof IProblemBinding)) {