1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-28 19:35:36 +02:00

Fixes for navigation + mark occurrences related to using-declarations.

This commit is contained in:
Markus Schorn 2008-02-01 14:49:21 +00:00
parent 0bb4c8bb9a
commit d0b1e7b4b4
12 changed files with 393 additions and 207 deletions

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2007 IBM Corporation and others. * Copyright (c) 2004, 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -11,9 +11,6 @@
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Andrew Ferguson (Symbian) * Andrew Ferguson (Symbian)
*******************************************************************************/ *******************************************************************************/
/*
* Created on Nov 29, 2004
*/
package org.eclipse.cdt.core.parser.tests.ast2; package org.eclipse.cdt.core.parser.tests.ast2;
import java.io.BufferedReader; import java.io.BufferedReader;
@ -76,11 +73,14 @@ import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTOperatorName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTOperatorName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember;
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.ICPPASTSimpleTypeConstructorExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeConstructorExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope;
@ -2939,7 +2939,7 @@ public class AST2CPPTests extends AST2BaseTest {
.resolveBinding(); .resolveBinding();
IASTName[] decls = tu.getDeclarationsInAST(u); IASTName[] decls = tu.getDeclarationsInAST(u);
assertEquals(decls.length, 2); assertEquals(3, decls.length); // 2 function-decls + using-decl
assertSame(decls[0], col.getName(1)); assertSame(decls[0], col.getName(1));
assertSame(decls[1], col.getName(3)); assertSame(decls[1], col.getName(3));
@ -2947,11 +2947,12 @@ public class AST2CPPTests extends AST2BaseTest {
assertEquals(delegates.length, 2); assertEquals(delegates.length, 2);
decls = tu.getDeclarationsInAST(delegates[0]); decls = tu.getDeclarationsInAST(delegates[0]);
assertEquals(decls.length, 1); assertEquals(2, decls.length); // function-decl + using-decl
assertSame(decls[0], col.getName(7)); assertSame(decls[0], col.getName(1));
assertSame(decls[1], col.getName(7));
decls = tu.getDeclarationsInAST(delegates[0].getBinding()); decls = tu.getDeclarationsInAST(delegates[0].getBinding());
assertEquals(decls.length, 1); assertEquals(1, decls.length);
assertSame(decls[0], col.getName(1)); assertSame(decls[0], col.getName(1));
} }
@ -3014,9 +3015,10 @@ public class AST2CPPTests extends AST2BaseTest {
ICPPUsingDeclaration comp = (ICPPUsingDeclaration) col.getName(7) ICPPUsingDeclaration comp = (ICPPUsingDeclaration) col.getName(7)
.resolveBinding(); .resolveBinding();
IASTName[] decls = tu.getDeclarationsInAST(comp); IASTName[] decls = tu.getDeclarationsInAST(comp);
assertEquals(decls.length, 2); assertEquals(3, decls.length); // struct, func and using-decl
assertSame(decls[0], col.getName(1)); assertSame(decls[0], col.getName(1));
assertSame(decls[1], col.getName(2)); assertSame(decls[1], col.getName(2));
assertSame(decls[2], col.getName(7));
} }
public void testBug86470_4() throws Exception { public void testBug86470_4() throws Exception {
@ -3051,8 +3053,9 @@ public class AST2CPPTests extends AST2BaseTest {
assertSame(x_var, ((ICPPDelegate) ref1).getBinding()); assertSame(x_var, ((ICPPDelegate) ref1).getBinding());
IASTName[] refs = tu.getReferences(x_struct); IASTName[] refs = tu.getReferences(x_struct);
assertEquals(refs.length, 1); assertEquals(2, refs.length); // 1 ref + using-decl
assertSame(refs[0], col.getName(10)); assertSame(refs[0], col.getName(10));
assertSame(refs[1], col.getName(12));
String[] s = ref2.getQualifiedName(); String[] s = ref2.getQualifiedName();
assertEquals(s[0], "x"); //$NON-NLS-1$ assertEquals(s[0], "x"); //$NON-NLS-1$
@ -5578,4 +5581,90 @@ public class AST2CPPTests extends AST2BaseTest {
assertInstance(b03, ICPPFunction.class); assertInstance(b03, ICPPFunction.class);
assertInstance(b09, ICPPFunction.class); assertInstance(b09, ICPPFunction.class);
} }
// namespace source {
// class cls {
// };
// void fs();
// void fs(int a);
//
// }
// void test1() {
// source::fs();
// source::fs(1);
// source::cls c2;
// }
//
// using source::cls;
// using source::fs;
//
// void test() {
// cls c2;
// fs();
// fs(1);
// }
public void testReferencesOfUsingDecls() throws Exception {
StringBuffer buffer = getContents(1)[0];
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP, true, true );
IASTDeclaration[] decls = tu.getDeclarations();
ICPPASTNamespaceDefinition nsdef= (ICPPASTNamespaceDefinition) decls[0];
ICPPASTUsingDeclaration udcl= (ICPPASTUsingDeclaration) decls[2];
ICPPASTUsingDeclaration udf= (ICPPASTUsingDeclaration) decls[3];
IASTFunctionDefinition fdef= (IASTFunctionDefinition) decls[4];
IASTDeclaration[] nsdecls= nsdef.getDeclarations();
ICPPASTCompositeTypeSpecifier cldef= (ICPPASTCompositeTypeSpecifier) ((IASTSimpleDeclaration) nsdecls[0]).getDeclSpecifier();
ICPPASTFunctionDeclarator fdecl1= (ICPPASTFunctionDeclarator) ((IASTSimpleDeclaration) nsdecls[1]).getDeclarators()[0];
ICPPASTFunctionDeclarator fdecl2= (ICPPASTFunctionDeclarator) ((IASTSimpleDeclaration) nsdecls[2]).getDeclarators()[0];
IASTStatement[] stmts= ((IASTCompoundStatement) fdef.getBody()).getStatements();
IASTName clname= ((IASTNamedTypeSpecifier) ((IASTSimpleDeclaration)((IASTDeclarationStatement) stmts[0]).getDeclaration()).getDeclSpecifier()).getName();
IASTName fnname1= ((IASTIdExpression) ((IASTFunctionCallExpression) ((IASTExpressionStatement) stmts[1]).getExpression()).getFunctionNameExpression()).getName();
IASTName fnname2= ((IASTIdExpression) ((IASTFunctionCallExpression) ((IASTExpressionStatement) stmts[2]).getExpression()).getFunctionNameExpression()).getName();
// check class
IBinding b= cldef.getName().resolveBinding();
assertEquals(3, tu.getReferences(b).length); // 2 refs + using-decl
assertEquals(1, tu.getDefinitionsInAST(b).length); // class-def
assertEquals(1, tu.getDeclarationsInAST(b).length); // class-def
// check functions
b= fdecl1.getName().resolveBinding();
assertEquals(3, tu.getReferences(b).length); // 2 refs + using-decl
assertEquals(0, tu.getDefinitionsInAST(b).length); // no def
assertEquals(1, tu.getDeclarationsInAST(b).length); // func-decl
b= fdecl2.getName().resolveBinding();
assertEquals(3, tu.getReferences(b).length); // 2 refs + using-decl
assertEquals(0, tu.getDefinitionsInAST(b).length); // no def
assertEquals(1, tu.getDeclarationsInAST(b).length); // func-decl
// check using declaration class
b= udcl.getName().resolveBinding();
assertEquals(3, tu.getReferences(b).length); // 2 refs + using-decl
assertEquals(2, tu.getDefinitionsInAST(b).length); // class-def + using-decl
assertEquals(2, tu.getDeclarationsInAST(b).length); // class-def + using-decl
// check using declaration function
b= udf.getName().resolveBinding();
assertEquals(5, tu.getReferences(b).length); // 4 refs + using-decl
assertEquals(1, tu.getDefinitionsInAST(b).length); // using-decl
assertEquals(3, tu.getDeclarationsInAST(b).length); // using-decl + 2 func-decls
// check class reference
b= clname.resolveBinding();
assertEquals(3, tu.getReferences(b).length); // 2 refs + using-decl
assertEquals(2, tu.getDefinitionsInAST(b).length); // class-def + using-decl
assertEquals(2, tu.getDeclarationsInAST(b).length); // class-def + using-decl
// check function references
b= fnname1.resolveBinding();
assertEquals(3, tu.getReferences(b).length); // 2 refs + using-decl
assertEquals(1, tu.getDefinitionsInAST(b).length); // using-decl
assertEquals(2, tu.getDeclarationsInAST(b).length); // using-decl + func-decl
b= fnname2.resolveBinding();
assertEquals(3, tu.getReferences(b).length); // 2 refs + using-decl
assertEquals(1, tu.getDefinitionsInAST(b).length); // using-decl
assertEquals(2, tu.getDeclarationsInAST(b).length); // using-decl + func-decl
}
} }

View file

@ -43,7 +43,11 @@ abstract public class BaseTestFramework extends TestCase {
static protected ICProject cproject; static protected ICProject cproject;
static protected FileManager fileManager; static protected FileManager fileManager;
static protected boolean indexDisabled=false; static protected boolean indexDisabled=false;
{
static void initProject() {
if (project != null) {
return;
}
if( CCorePlugin.getDefault() != null && CCorePlugin.getDefault().getCoreModel() != null){ if( CCorePlugin.getDefault() != null && CCorePlugin.getDefault().getCoreModel() != null){
//(CCorePlugin.getDefault().getCoreModel().getIndexManager()).reset(); //(CCorePlugin.getDefault().getCoreModel().getIndexManager()).reset();
monitor = new NullProgressMonitor(); monitor = new NullProgressMonitor();
@ -88,12 +92,19 @@ abstract public class BaseTestFramework extends TestCase {
public void cleanupProject() throws Exception { public void cleanupProject() throws Exception {
try{ try{
project.delete( true, false, monitor ); project.delete( true, false, monitor );
project = null;
} catch( Throwable e ){ } catch( Throwable e ){
/*boo*/ /*boo*/
} finally {
project= null;
} }
} }
@Override
protected void setUp() throws Exception {
super.setUp();
initProject();
}
protected void tearDown() throws Exception { protected void tearDown() throws Exception {
if( project == null || !project.exists() ) if( project == null || !project.exists() )
return; return;

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2006, 2007 Wind River Systems, Inc. and others. * Copyright (c) 2006, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -8,7 +8,6 @@
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.model.ext; package org.eclipse.cdt.internal.core.model.ext;
import org.eclipse.cdt.core.dom.IName; import org.eclipse.cdt.core.dom.IName;
@ -28,6 +27,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
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.ICPPNamespaceScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
@ -69,6 +69,13 @@ public class CElementHandleFactory {
public static ICElementHandle internalCreate(ITranslationUnit tu, IBinding binding, boolean definition, public static ICElementHandle internalCreate(ITranslationUnit tu, IBinding binding, boolean definition,
IRegion region, long timestamp) throws CoreException, DOMException { IRegion region, long timestamp) throws CoreException, DOMException {
if (binding instanceof ICPPDelegate) {
ICPPDelegate delegate= (ICPPDelegate) binding;
if (delegate.getDelegateType() == ICPPDelegate.USING_DECLARATION) {
binding= delegate.getBinding();
}
}
ICElement parentElement= create(tu, binding.getScope()); ICElement parentElement= create(tu, binding.getScope());
if (parentElement == null) { if (parentElement == null) {
return null; return null;

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2007 IBM Corporation and others. * Copyright (c) 2004, 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -8,6 +8,7 @@
* Contributors: * Contributors:
* IBM - Initial API and implementation * IBM - Initial API and implementation
* Bryan Wilkinson (QNX) * Bryan Wilkinson (QNX)
* Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -80,13 +81,13 @@ public class CPPASTUsingDeclaration extends CPPASTNode implements
public int getRoleForName(IASTName n) { public int getRoleForName(IASTName n) {
if( n == name ) if( n == name )
return r_reference; return r_definition;
return r_unclear; return r_unclear;
} }
public IBinding[] findBindings(IASTName n, boolean isPrefix) { public IBinding[] findBindings(IASTName n, boolean isPrefix) {
IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix); IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix);
List filtered = new ArrayList(); List<IBinding> filtered = new ArrayList<IBinding>();
for (int i = 0;i < bindings.length; i++) { for (int i = 0;i < bindings.length; i++) {
if (bindings[i] instanceof ICPPNamespace) { if (bindings[i] instanceof ICPPNamespace) {
@ -94,6 +95,6 @@ public class CPPASTUsingDeclaration extends CPPASTNode implements
} }
} }
return (IBinding[]) filtered.toArray(new IBinding[filtered.size()]); return filtered.toArray(new IBinding[filtered.size()]);
} }
} }

View file

@ -113,6 +113,9 @@ public class CPPDelegate extends PlatformObject implements ICPPDelegate, ICPPInt
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#getDefinition() * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#getDefinition()
*/ */
public IASTNode getDefinition() { public IASTNode getDefinition() {
if (usingDeclaration instanceof ICPPInternalBinding) {
return ((ICPPInternalBinding) usingDeclaration).getDefinition();
}
return null; return null;
} }
@ -153,4 +156,8 @@ public class CPPDelegate extends PlatformObject implements ICPPDelegate, ICPPInt
public ILinkage getLinkage() { public ILinkage getLinkage() {
return Linkage.CPP_LINKAGE; return Linkage.CPP_LINKAGE;
} }
public ICPPUsingDeclaration getUsingDeclaration() {
return usingDeclaration;
}
} }

View file

@ -10,7 +10,6 @@
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Andrew Ferguson (Symbian) * Andrew Ferguson (Symbian)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.IName; import org.eclipse.cdt.core.dom.IName;
@ -1105,7 +1104,7 @@ public class CPPVisitor {
public static class CollectDeclarationsAction extends CPPASTVisitor { public static class CollectDeclarationsAction extends CPPASTVisitor {
private static final int DEFAULT_LIST_SIZE = 8; private static final int DEFAULT_LIST_SIZE = 8;
private IASTName [] decls; private IASTName [] decls;
private IBinding binding; private IBinding[] bindings;
private int idx = 0; private int idx = 0;
private int kind; private int kind;
@ -1118,11 +1117,23 @@ public class CPPVisitor {
public CollectDeclarationsAction( IBinding binding ){ public CollectDeclarationsAction( IBinding binding ){
this.binding = binding; shouldVisitNames = true;
this.decls = new IASTName[ DEFAULT_LIST_SIZE ]; this.decls = new IASTName[ DEFAULT_LIST_SIZE ];
shouldVisitNames = true; this.bindings = new IBinding[] {binding};
if( binding instanceof ILabel ) if (binding instanceof ICPPUsingDeclaration) {
try {
ICPPDelegate[] delegates= ((ICPPUsingDeclaration) binding).getDelegates();
this.bindings= new IBinding[delegates.length+1];
this.bindings[0]= binding;
for (int i=0; i < delegates.length; i++) {
this.bindings[i+1]= delegates[i].getBinding();
}
} catch (DOMException e) {
}
kind= KIND_COMPOSITE;
}
else if( binding instanceof ILabel )
kind = KIND_LABEL; kind = KIND_LABEL;
else if( binding instanceof ICPPTemplateParameter ) else if( binding instanceof ICPPTemplateParameter )
kind = KIND_TEMPLATE_PARAMETER; kind = KIND_TEMPLATE_PARAMETER;
@ -1135,8 +1146,6 @@ public class CPPVisitor {
else if( binding instanceof ICPPNamespace) { else if( binding instanceof ICPPNamespace) {
kind = KIND_NAMESPACE; kind = KIND_NAMESPACE;
} }
else if( binding instanceof ICPPUsingDeclaration )
kind = KIND_COMPOSITE;
else else
kind = KIND_OBJ_FN; kind = KIND_OBJ_FN;
} }
@ -1212,50 +1221,8 @@ public class CPPVisitor {
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
if( binding != null ) if( bindings != null ) {
{ if (isDeclarationsBinding(name.resolveBinding())) {
IBinding potential = name.resolveBinding();
IBinding [] bs = null;
IBinding candidate = null;
int n = -1;
if( potential instanceof ICPPUsingDeclaration ){
try {
bs = ((ICPPUsingDeclaration)potential).getDelegates();
} catch ( DOMException e ) {
return PROCESS_CONTINUE;
}
if( bs == null || bs.length == 0 )
candidate = null;
else
candidate = bs[ ++n ];
} else {
candidate = potential;
}
while( candidate != null ) {
boolean found = false;
if( binding instanceof ICPPUsingDeclaration ){
ICPPDelegate [] delegates = null;
try {
delegates = ((ICPPUsingDeclaration)binding).getDelegates();
} catch (DOMException e1) {
}
if( delegates != null ){
for (int i = 0; i < delegates.length; i++) {
if( delegates[i].getBinding() == candidate ){
found = true;
break;
}
}
}
} else {
// if( candidate instanceof ICPPDelegate )
// found = ( ((ICPPDelegate)candidate).getBinding() == binding );
// else
found = ( binding == candidate );
}
if( found ){
if( decls.length == idx ){ if( decls.length == idx ){
IASTName [] temp = new IASTName[ decls.length * 2 ]; IASTName [] temp = new IASTName[ decls.length * 2 ];
System.arraycopy( decls, 0, temp, 0, decls.length ); System.arraycopy( decls, 0, temp, 0, decls.length );
@ -1263,13 +1230,31 @@ public class CPPVisitor {
} }
decls[idx++] = name; decls[idx++] = name;
} }
if( n > -1 && ++n < bs.length ){
candidate = bs[n];
} else break;
}
} }
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
private boolean isDeclarationsBinding(IBinding nameBinding) {
nameBinding= unwindBinding(nameBinding);
if (nameBinding != null) {
for (int i = 0; i < bindings.length; i++) {
if (nameBinding.equals(unwindBinding(bindings[i]))) {
return true;
}
// a using declaration is a declaration for the references of its delegates
if (nameBinding instanceof ICPPUsingDeclaration) {
try {
if (ArrayUtil.contains(((ICPPUsingDeclaration) nameBinding).getDelegates(), bindings[i])) {
return true;
}
} catch (DOMException e) {
}
}
}
}
return false;
}
public IASTName[] getDeclarations(){ public IASTName[] getDeclarations(){
if( idx < decls.length ){ if( idx < decls.length ){
IASTName [] temp = new IASTName[ idx ]; IASTName [] temp = new IASTName[ idx ];
@ -1280,10 +1265,29 @@ public class CPPVisitor {
} }
} }
protected static IBinding unwindBinding(IBinding binding) {
while(true) {
if (binding instanceof ICPPSpecialization) {
binding= ((ICPPSpecialization) binding).getSpecializedBinding();
} else if (binding instanceof ICPPDelegate) {
ICPPDelegate delegate= (ICPPDelegate) binding;
if (delegate.getDelegateType() == ICPPDelegate.USING_DECLARATION) {
binding= delegate.getBinding();
} else {
break;
}
} else {
break;
}
}
return binding;
}
public static class CollectReferencesAction extends CPPASTVisitor { public static class CollectReferencesAction extends CPPASTVisitor {
private static final int DEFAULT_LIST_SIZE = 8; private static final int DEFAULT_LIST_SIZE = 8;
private IASTName [] refs; private IASTName [] refs;
private IBinding binding; private IBinding[] bindings;
private int idx = 0; private int idx = 0;
private int kind; private int kind;
@ -1295,29 +1299,36 @@ public class CPPVisitor {
public CollectReferencesAction( IBinding binding ){ public CollectReferencesAction( IBinding binding ){
if (binding instanceof ICPPSpecialization) { shouldVisitNames = true;
binding= ((ICPPSpecialization) binding).getSpecializedBinding();
}
this.binding = binding;
this.refs = new IASTName[ DEFAULT_LIST_SIZE ]; this.refs = new IASTName[ DEFAULT_LIST_SIZE ];
shouldVisitNames = true; binding = unwindBinding(binding);
if( binding instanceof ILabel ) this.bindings = new IBinding[] {binding};
kind = KIND_LABEL;
else if( binding instanceof ICompositeType || if (binding instanceof ICPPUsingDeclaration) {
binding instanceof ITypedef || try {
binding instanceof IEnumeration) ICPPDelegate[] delegates= ((ICPPUsingDeclaration) binding).getDelegates();
{ this.bindings= new IBinding[delegates.length];
kind = KIND_TYPE; for (int i = 0; i < delegates.length; i++) {
binding= this.bindings[i]= delegates[i].getBinding();
} }
else if( binding instanceof ICPPNamespace) { } catch (DOMException e) {
}
kind= KIND_COMPOSITE;
} else if( binding instanceof ILabel ) {
kind = KIND_LABEL;
} else if( binding instanceof ICompositeType ||
binding instanceof ITypedef ||
binding instanceof IEnumeration) {
kind = KIND_TYPE;
} else if( binding instanceof ICPPNamespace) {
kind = KIND_NAMESPACE; kind = KIND_NAMESPACE;
} else if( binding instanceof ICPPUsingDeclaration || } else if( binding instanceof ICPPTemplateParameter ) {
binding instanceof ICPPTemplateParameter )
kind = KIND_COMPOSITE; kind = KIND_COMPOSITE;
else } else {
kind = KIND_OBJ_FN; kind = KIND_OBJ_FN;
} }
}
public int visit( IASTName name ){ public int visit( IASTName name ){
if( name instanceof ICPPASTQualifiedName || name instanceof ICPPASTTemplateId ) return PROCESS_CONTINUE; if( name instanceof ICPPASTQualifiedName || name instanceof ICPPASTTemplateId ) return PROCESS_CONTINUE;
@ -1382,63 +1393,46 @@ public class CPPVisitor {
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
if( binding != null ){ if( bindings != null ){
IBinding potential = name.resolveBinding(); if (isReferenceBinding(name.resolveBinding())) {
IBinding [] bs = null; if (refs.length == idx){
IBinding candidate = null;
int n = -1;
if( potential instanceof ICPPUsingDeclaration ){
try {
bs = ((ICPPUsingDeclaration)potential).getDelegates();
} catch ( DOMException e ) {
return PROCESS_CONTINUE;
}
if( bs == null || bs.length == 0 )
candidate = null;
else
candidate = bs[ ++n ];
} else if (potential instanceof ICPPSpecialization) {
candidate= ((ICPPSpecialization) potential).getSpecializedBinding();
} else {
candidate = potential;
}
while( candidate != null ) {
boolean found = false;
if( binding instanceof ICPPUsingDeclaration ){
try {
found = ArrayUtil.containsEqual( ((ICPPUsingDeclaration)binding).getDelegates(), candidate );
} catch ( DOMException e ) {
}
} else if( potential instanceof ICPPUsingDeclaration ){
found = sameBinding(binding, ((ICPPDelegate)candidate).getBinding());
} else {
found = sameBinding(binding, candidate);
}
if( found ){
if( refs.length == idx ){
IASTName [] temp = new IASTName[ refs.length * 2 ]; IASTName [] temp = new IASTName[ refs.length * 2 ];
System.arraycopy( refs, 0, temp, 0, refs.length ); System.arraycopy( refs, 0, temp, 0, refs.length );
refs = temp; refs = temp;
} }
refs[idx++] = name; refs[idx++] = name;
break;
}
if( n > -1 && ++n < bs.length ){
candidate = bs[n];
} else break;
} }
} }
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
private boolean sameBinding(IBinding binding1, IBinding binding2) {
if (binding1 == binding2) private boolean isReferenceBinding(IBinding nameBinding) {
nameBinding= unwindBinding(nameBinding);
if (nameBinding != null) {
for (int i = 0; i < bindings.length; i++) {
if (nameBinding.equals(bindings[i])) {
return true; return true;
if (binding1.equals(binding2)) }
}
if (nameBinding instanceof ICPPUsingDeclaration) {
try {
ICPPDelegate[] delegates= ((ICPPUsingDeclaration) nameBinding).getDelegates();
for (int i = 0; i < delegates.length; i++) {
ICPPDelegate delegate = delegates[i];
if (isReferenceBinding(delegate.getBinding())) {
return true; return true;
}
}
} catch (DOMException e) {
}
return false;
} else {
return false; return false;
} }
}
return false;
}
public IASTName[] getReferences(){ public IASTName[] getReferences(){
if( idx < refs.length ){ if( idx < refs.length ){
IASTName [] temp = new IASTName[ idx ]; IASTName [] temp = new IASTName[ idx ];

View file

@ -11,7 +11,6 @@
* Andrew Ferguson (Symbian) * Andrew Ferguson (Symbian)
* Anton Leherbauer (Wind River Systems) * Anton Leherbauer (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.index; package org.eclipse.cdt.internal.core.index;
import java.util.ArrayList; import java.util.ArrayList;
@ -31,6 +30,7 @@ import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
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.cpp.ICPPDelegate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexBinding;
@ -42,6 +42,7 @@ import org.eclipse.cdt.core.index.IIndexMacro;
import org.eclipse.cdt.core.index.IIndexName; import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.core.index.IndexFilter; import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDelegate;
import org.eclipse.cdt.internal.core.index.composite.CompositingNotImplementedError; import org.eclipse.cdt.internal.core.index.composite.CompositingNotImplementedError;
import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory; import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory;
import org.eclipse.cdt.internal.core.index.composite.c.CCompositesFactory; import org.eclipse.cdt.internal.core.index.composite.c.CCompositesFactory;
@ -122,8 +123,9 @@ public class CIndex implements IIndex {
} }
public IIndexName[] findNames(IBinding binding, int flags) throws CoreException { public IIndexName[] findNames(IBinding binding, int flags) throws CoreException {
LinkedList<IIndexFragmentName> result= new LinkedList<IIndexFragmentName>();
if (binding instanceof ICPPUsingDeclaration) { if (binding instanceof ICPPUsingDeclaration) {
IBinding[] bindings= null; ICPPDelegate[] bindings= null;
try { try {
bindings = ((ICPPUsingDeclaration)binding).getDelegates(); bindings = ((ICPPUsingDeclaration)binding).getDelegates();
} catch (DOMException e) { } catch (DOMException e) {
@ -133,16 +135,26 @@ public class CIndex implements IIndex {
return new IIndexName[0]; return new IIndexName[0];
} }
if (bindings.length > 1) { if (bindings.length > 1) {
ArrayList<IIndexName> result= new ArrayList<IIndexName>(); ArrayList<IIndexName> multi= new ArrayList<IIndexName>();
for (int i = 0; i < bindings.length; i++) { for (int i = 0; i < bindings.length; i++) {
IBinding b = bindings[i]; IBinding b = bindings[i];
result.addAll(Arrays.asList(findNames(b, flags))); multi.addAll(Arrays.asList(findNames(b, flags)));
} }
return result.toArray(new IIndexName[result.size()]); return multi.toArray(new IIndexName[multi.size()]);
} }
binding= bindings[0]; binding= bindings[0];
} else if (binding instanceof CPPDelegate) {
CPPDelegate delegate= (CPPDelegate) binding;
if (delegate.getDelegateType() == ICPPDelegate.USING_DECLARATION) {
binding= delegate.getBinding();
IIndexFragmentBinding ib= (IIndexFragmentBinding) delegate.getUsingDeclaration().getAdapter(IIndexFragmentBinding.class);
if (ib != null) {
final IIndexFragmentName[] names= ib.getFragment().findNames(ib, flags);
result.addAll(Arrays.asList(names));
} }
LinkedList<IIndexFragmentName> result= new LinkedList<IIndexFragmentName>(); }
}
int fragCount= 0; int fragCount= 0;
for (int i = 0; i < fPrimaryFragmentCount; i++) { for (int i = 0; i < fPrimaryFragmentCount; i++) {
final IIndexFragmentName[] names = fFragments[i].findNames(binding, flags); final IIndexFragmentName[] names = fFragments[i].findNames(binding, flags);

View file

@ -11,7 +11,6 @@
* IBM Corporation * IBM Corporation
* Andrew Ferguson (Symbian) * Andrew Ferguson (Symbian)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom; package org.eclipse.cdt.internal.core.pdom.dom;
import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ILinkage;
@ -36,7 +35,6 @@ import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDeferredTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPDeferredTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceAlias;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition;
@ -261,8 +259,12 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
} else { } else {
// in case this is a delegate the scope of the delegate can be different to the // in case this is a delegate the scope of the delegate can be different to the
// scope of the delegating party (e.g. using-declarations) // scope of the delegating party (e.g. using-declarations)
while (binding instanceof ICPPDelegate && !(binding instanceof ICPPNamespaceAlias)) { while (binding instanceof ICPPDelegate) {
binding= ((ICPPDelegate) binding).getBinding(); final ICPPDelegate delegate = (ICPPDelegate)binding;
if (delegate.getDelegateType() != ICPPDelegate.USING_DECLARATION) {
break;
}
binding= delegate.getBinding();
} }
IScope scope = binding.getScope(); IScope scope = binding.getScope();
if (scope == null) { if (scope == null) {
@ -356,17 +358,19 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
if (binding instanceof IField) { if (binding instanceof IField) {
return null; return null;
} }
boolean isFileLocal= false; boolean checkInSourceOnly= false;
if (binding instanceof IVariable) { if (binding instanceof IVariable) {
if (!(binding instanceof IField)) { if (!(binding instanceof IField)) {
isFileLocal= ASTInternal.isStatic((IVariable) binding); checkInSourceOnly= ASTInternal.isStatic((IVariable) binding);
} }
} else if (binding instanceof IFunction) { } else if (binding instanceof IFunction) {
IFunction f= (IFunction) binding; IFunction f= (IFunction) binding;
isFileLocal= ASTInternal.isStatic(f, false); checkInSourceOnly= ASTInternal.isStatic(f, false);
// } else if (binding instanceof ITypedef || binding instanceof ICompositeType || binding instanceof IEnumeration) {
// checkInSourceOnly= true;
} }
if (isFileLocal) { if (checkInSourceOnly) {
String path= ASTInternal.getDeclaredInSourceFileOnly(binding); String path= ASTInternal.getDeclaredInSourceFileOnly(binding);
if (path != null) { if (path != null) {
return wpdom.getFileForASTPath(getLinkageID(), path); return wpdom.getFileForASTPath(getLinkageID(), path);

View file

@ -17,7 +17,6 @@ import java.util.ArrayList;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
import org.eclipse.cdt.core.index.IIndexFile; import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexName; import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.internal.core.index.IIndexFragment; import org.eclipse.cdt.internal.core.index.IIndexFragment;
@ -105,11 +104,6 @@ public final class PDOMName implements IIndexFragmentName, IASTFileLocation {
if (name.isDeclaration()) { if (name.isDeclaration()) {
return IS_DECLARATION; return IS_DECLARATION;
} }
// special case a using-declaration is a declaration and a reference at the same time.
if (name.getBinding() instanceof ICPPUsingDeclaration) {
return IS_DEFINITION;
}
return IS_REFERENCE; return IS_REFERENCE;
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2007 IBM Corporation and others. * Copyright (c) 2004, 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -80,7 +80,12 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase {
static ICProject cPrj; static ICProject cPrj;
static FileManager fileManager; static FileManager fileManager;
static boolean disabledHelpContributions = false; static boolean disabledHelpContributions = false;
{
static void initProject() {
if (project != null) {
return;
}
//(CCorePlugin.getDefault().getCoreModel().getIndexManager()).reset(); //(CCorePlugin.getDefault().getCoreModel().getIndexManager()).reset();
monitor = new NullProgressMonitor(); monitor = new NullProgressMonitor();
@ -126,14 +131,19 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase {
closeAllEditors(); closeAllEditors();
try{ try{
project.delete( true, false, monitor ); project.delete( true, false, monitor );
project = null; } catch( CoreException e ){
} catch( Throwable e ){ try {
/*boo*/ project.delete( true, false, monitor );
}
catch (CoreException e1) {}
} finally {
project= null;
} }
} }
protected void setUp() throws Exception { protected void setUp() throws Exception {
super.setUp(); super.setUp();
initProject();
OpenDeclarationsAction.sIsJUnitTest= true; OpenDeclarationsAction.sIsJUnitTest= true;
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2007 IBM Corporation and others. * Copyright (c) 2004, 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -75,7 +75,11 @@ public class CSelectionTestsNoIndexer extends BaseUITestCase {
static ICProject cPrj; static ICProject cPrj;
static FileManager fileManager; static FileManager fileManager;
static boolean disabledHelpContributions = false; static boolean disabledHelpContributions = false;
{
void initProject() {
if (project != null) {
return;
}
//(CCorePlugin.getDefault().getCoreModel().getIndexManager()).reset(); //(CCorePlugin.getDefault().getCoreModel().getIndexManager()).reset();
monitor = new NullProgressMonitor(); monitor = new NullProgressMonitor();
@ -114,13 +118,19 @@ public class CSelectionTestsNoIndexer extends BaseUITestCase {
protected void setUp() throws Exception { protected void setUp() throws Exception {
super.setUp(); super.setUp();
OpenDeclarationsAction.sIsJUnitTest= true; OpenDeclarationsAction.sIsJUnitTest= true;
initProject();
} }
public void cleanupProject() throws Exception { public void cleanupProject() throws Exception {
try {
closeAllEditors(); closeAllEditors();
CProjectHelper.delete(cPrj); CProjectHelper.delete(cPrj);
project= null; project= null;
} }
finally {
project= null;
}
}
protected void tearDown() throws Exception { protected void tearDown() throws Exception {
if( project == null || !project.exists() ) if( project == null || !project.exists() )

View file

@ -10,7 +10,6 @@
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Ed Swartz (Nokia) * Ed Swartz (Nokia)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.ui.search.actions; package org.eclipse.cdt.internal.ui.search.actions;
import java.util.ArrayList; import java.util.ArrayList;
@ -41,6 +40,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexManager; import org.eclipse.cdt.core.index.IIndexManager;
import org.eclipse.cdt.core.index.IIndexName; import org.eclipse.cdt.core.index.IIndexName;
@ -81,6 +81,10 @@ public class OpenDeclarationsAction extends SelectionParseAction {
} }
private class Runner extends Job implements ASTRunnable { private class Runner extends Job implements ASTRunnable {
private static final int KIND_OTHER = 0;
private static final int KIND_USING_DECL = 1;
private static final int KIND_DEFINITION = 2;
private IWorkingCopy fWorkingCopy; private IWorkingCopy fWorkingCopy;
private IIndex fIndex; private IIndex fIndex;
@ -132,16 +136,23 @@ public class OpenDeclarationsAction extends SelectionParseAction {
openInclude(((IASTPreprocessorIncludeStatement) parent)); openInclude(((IASTPreprocessorIncludeStatement) parent));
return Status.OK_STATUS; return Status.OK_STATUS;
} }
boolean isDefinition= searchName.isDefinition();
IBinding binding = searchName.resolveBinding(); IBinding binding = searchName.resolveBinding();
if (binding != null && !(binding instanceof IProblemBinding)) { if (binding != null && !(binding instanceof IProblemBinding)) {
IName[] declNames = findNames(fIndex, ast, isDefinition, binding); int isKind= KIND_OTHER;
if (searchName.isDefinition()) {
if (binding instanceof ICPPUsingDeclaration) {
isKind= KIND_USING_DECL;
} else {
isKind= KIND_DEFINITION;
}
}
IName[] declNames = findNames(fIndex, ast, isKind, binding);
if (declNames.length == 0) { if (declNames.length == 0) {
if (binding instanceof ICPPSpecialization) { if (binding instanceof ICPPSpecialization) {
// bug 207320, handle template instances // bug 207320, handle template instances
IBinding specialized= ((ICPPSpecialization) binding).getSpecializedBinding(); IBinding specialized= ((ICPPSpecialization) binding).getSpecializedBinding();
if (specialized != null && !(specialized instanceof IProblemBinding)) { if (specialized != null && !(specialized instanceof IProblemBinding)) {
declNames = findNames(fIndex, ast, true, specialized); declNames = findNames(fIndex, ast, KIND_DEFINITION, specialized);
} }
} else if (binding instanceof ICPPMethod) { } else if (binding instanceof ICPPMethod) {
// bug 86829, handle implicit methods. // bug 86829, handle implicit methods.
@ -150,7 +161,7 @@ public class OpenDeclarationsAction extends SelectionParseAction {
try { try {
IBinding clsBinding= method.getClassOwner(); IBinding clsBinding= method.getClassOwner();
if (clsBinding != null && !(clsBinding instanceof IProblemBinding)) { if (clsBinding != null && !(clsBinding instanceof IProblemBinding)) {
declNames= findNames(fIndex, ast, false, clsBinding); declNames= findNames(fIndex, ast, KIND_OTHER, clsBinding);
} }
} catch (DOMException e) { } catch (DOMException e) {
// don't log problem bindings. // don't log problem bindings.
@ -239,7 +250,7 @@ public class OpenDeclarationsAction extends SelectionParseAction {
} }
private boolean navigateViaCElements(ICProject project, IIndex index, IName[] declNames) { private boolean navigateViaCElements(ICProject project, IIndex index, IName[] declNames) {
final ArrayList elements= new ArrayList(); final ArrayList<ICElement> elements= new ArrayList<ICElement>();
for (int i = 0; i < declNames.length; i++) { for (int i = 0; i < declNames.length; i++) {
try { try {
ICElement elem = getCElementForName(project, index, declNames[i]); ICElement elem = getCElementForName(project, index, declNames[i]);
@ -264,7 +275,7 @@ public class OpenDeclarationsAction extends SelectionParseAction {
if (sIsJUnitTest) { if (sIsJUnitTest) {
throw new RuntimeException("ambiguous input"); //$NON-NLS-1$ throw new RuntimeException("ambiguous input"); //$NON-NLS-1$
} }
ICElement[] elemArray= (ICElement[]) elements.toArray(new ICElement[elements.size()]); ICElement[] elemArray= elements.toArray(new ICElement[elements.size()]);
target = (ISourceReference) OpenActionUtil.selectCElement(elemArray, getSite().getShell(), target = (ISourceReference) OpenActionUtil.selectCElement(elemArray, getSite().getShell(),
CEditorMessages.getString("OpenDeclarationsAction.dialog.title"), CEditorMessages.getString("OpenDeclarationsAction.selectMessage"), //$NON-NLS-1$ //$NON-NLS-2$ CEditorMessages.getString("OpenDeclarationsAction.dialog.title"), CEditorMessages.getString("OpenDeclarationsAction.selectMessage"), //$NON-NLS-1$ //$NON-NLS-2$
CElementBaseLabels.ALL_DEFAULT | CElementBaseLabels.MF_POST_FILE_QUALIFIED, 0); CElementBaseLabels.ALL_DEFAULT | CElementBaseLabels.MF_POST_FILE_QUALIFIED, 0);
@ -307,28 +318,64 @@ public class OpenDeclarationsAction extends SelectionParseAction {
return null; return null;
} }
private IName[] findNames(IIndex index, IASTTranslationUnit ast, private IName[] findNames(IIndex index, IASTTranslationUnit ast, int isKind, IBinding binding) throws CoreException {
boolean isDefinition, IBinding binding) throws CoreException { IName[] declNames;
IName[] declNames= isDefinition ? if (isKind == KIND_DEFINITION) {
findDeclarations(index, ast, binding) : declNames= findDeclarations(index, ast, binding);
findDefinitions(index, ast, binding); } else {
declNames= findDefinitions(index, ast, isKind, binding);
}
if (declNames.length == 0) { if (declNames.length == 0) {
declNames= isDefinition ? if (isKind == KIND_DEFINITION) {
findDefinitions(index, ast, binding) : declNames= findDefinitions(index, ast, isKind, binding);
findDeclarations(index, ast, binding); } else {
declNames= findDeclarations(index, ast, binding);
}
} }
return declNames; return declNames;
} }
private IName[] findDefinitions(IIndex index, IASTTranslationUnit ast, private IName[] findDefinitions(IIndex index, IASTTranslationUnit ast, int isKind, IBinding binding) throws CoreException {
IBinding binding) throws CoreException { IASTName[] declNames= ast.getDefinitionsInAST(binding);
IName[] declNames= ast.getDefinitionsInAST(binding); boolean containsUsingDirectives= false;
if (declNames.length == 0) { for (int i = 0; i < declNames.length; i++) {
IASTName name= declNames[i];
if (name.resolveBinding() instanceof ICPPUsingDeclaration) {
containsUsingDirectives= true;
break;
}
}
if (containsUsingDirectives) {
// prevent navigation from using-decl to itself, or prefer using-decls over original defs.
declNames= separateUsingDecls(declNames, isKind != KIND_USING_DECL);
}
if (declNames.length > 0) {
return declNames;
}
// 2. Try definition in index // 2. Try definition in index
declNames = index.findNames(binding, IIndex.FIND_DEFINITIONS | IIndex.SEARCH_ACCROSS_LANGUAGE_BOUNDARIES); IIndexName[] inames= index.findNames(binding, IIndex.FIND_DEFINITIONS | IIndex.SEARCH_ACCROSS_LANGUAGE_BOUNDARIES);
if (isKind != KIND_USING_DECL) {
// prefer using decls
for (int i = 0; i < inames.length; i++) {
if (index.findBinding(inames[i]) instanceof ICPPUsingDeclaration) {
return new IName[]{inames[i]};
} }
return declNames; }
}
return inames;
}
private IASTName[] separateUsingDecls(IASTName[] declNames, boolean keep) {
ArrayList<IASTName> result= new ArrayList<IASTName>(declNames.length);
for (int i = 0; i < declNames.length; i++) {
IASTName name = declNames[i];
if (keep == (name.resolveBinding() instanceof ICPPUsingDeclaration)) {
result.add(name);
}
}
return result.toArray(new IASTName[result.size()]);
} }
private IName[] findDeclarations(IIndex index, IASTTranslationUnit ast, private IName[] findDeclarations(IIndex index, IASTTranslationUnit ast,