From d0b1e7b4b448b3932a6a7e175562d578c015c377 Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Fri, 1 Feb 2008 14:49:21 +0000 Subject: Fixes for navigation + mark occurrences related to using-declarations. --- .../cdt/core/parser/tests/ast2/AST2CPPTests.java | 109 ++++++++- .../eclipse/cdt/core/tests/BaseTestFramework.java | 17 +- .../core/model/ext/CElementHandleFactory.java | 13 +- .../dom/parser/cpp/CPPASTUsingDeclaration.java | 13 +- .../internal/core/dom/parser/cpp/CPPDelegate.java | 7 + .../internal/core/dom/parser/cpp/CPPVisitor.java | 248 ++++++++++----------- .../eclipse/cdt/internal/core/index/CIndex.java | 24 +- .../cdt/internal/core/pdom/dom/PDOMLinkage.java | 22 +- .../cdt/internal/core/pdom/dom/PDOMName.java | 6 - .../text/selection/CPPSelectionTestsNoIndexer.java | 24 +- .../text/selection/CSelectionTestsNoIndexer.java | 24 +- .../ui/search/actions/OpenDeclarationsAction.java | 91 ++++++-- 12 files changed, 392 insertions(+), 206 deletions(-) (limited to 'core') diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index e8fac54c7d3..e40b800d5be 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -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 * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -11,9 +11,6 @@ * Markus Schorn (Wind River Systems) * Andrew Ferguson (Symbian) *******************************************************************************/ -/* - * Created on Nov 29, 2004 - */ package org.eclipse.cdt.core.parser.tests.ast2; 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.ICPPASTCompositeTypeSpecifier; 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.ICPPASTNamespaceDefinition; 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.ICPPASTQualifiedName; 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.ICPPBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope; @@ -2939,7 +2939,7 @@ public class AST2CPPTests extends AST2BaseTest { .resolveBinding(); 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[1], col.getName(3)); @@ -2947,11 +2947,12 @@ public class AST2CPPTests extends AST2BaseTest { assertEquals(delegates.length, 2); decls = tu.getDeclarationsInAST(delegates[0]); - assertEquals(decls.length, 1); - assertSame(decls[0], col.getName(7)); + assertEquals(2, decls.length); // function-decl + using-decl + assertSame(decls[0], col.getName(1)); + assertSame(decls[1], col.getName(7)); decls = tu.getDeclarationsInAST(delegates[0].getBinding()); - assertEquals(decls.length, 1); + assertEquals(1, decls.length); assertSame(decls[0], col.getName(1)); } @@ -3014,9 +3015,10 @@ public class AST2CPPTests extends AST2BaseTest { ICPPUsingDeclaration comp = (ICPPUsingDeclaration) col.getName(7) .resolveBinding(); 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[1], col.getName(2)); + assertSame(decls[2], col.getName(7)); } public void testBug86470_4() throws Exception { @@ -3051,8 +3053,9 @@ public class AST2CPPTests extends AST2BaseTest { assertSame(x_var, ((ICPPDelegate) ref1).getBinding()); 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[1], col.getName(12)); String[] s = ref2.getQualifiedName(); assertEquals(s[0], "x"); //$NON-NLS-1$ @@ -5578,4 +5581,90 @@ public class AST2CPPTests extends AST2BaseTest { assertInstance(b03, 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 + } } diff --git a/core/org.eclipse.cdt.core.tests/regression/org/eclipse/cdt/core/tests/BaseTestFramework.java b/core/org.eclipse.cdt.core.tests/regression/org/eclipse/cdt/core/tests/BaseTestFramework.java index aee1feda4cb..0745d180785 100644 --- a/core/org.eclipse.cdt.core.tests/regression/org/eclipse/cdt/core/tests/BaseTestFramework.java +++ b/core/org.eclipse.cdt.core.tests/regression/org/eclipse/cdt/core/tests/BaseTestFramework.java @@ -43,7 +43,11 @@ abstract public class BaseTestFramework extends TestCase { static protected ICProject cproject; static protected FileManager fileManager; static protected boolean indexDisabled=false; - { + + static void initProject() { + if (project != null) { + return; + } if( CCorePlugin.getDefault() != null && CCorePlugin.getDefault().getCoreModel() != null){ //(CCorePlugin.getDefault().getCoreModel().getIndexManager()).reset(); monitor = new NullProgressMonitor(); @@ -88,13 +92,20 @@ abstract public class BaseTestFramework extends TestCase { public void cleanupProject() throws Exception { try{ project.delete( true, false, monitor ); - project = null; } catch( Throwable e ){ /*boo*/ + } finally { + project= null; } } - protected void tearDown() throws Exception { + @Override + protected void setUp() throws Exception { + super.setUp(); + initProject(); + } + + protected void tearDown() throws Exception { if( project == null || !project.exists() ) return; diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ext/CElementHandleFactory.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ext/CElementHandleFactory.java index 7794c5e6afe..bd095e552ae 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ext/CElementHandleFactory.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ext/CElementHandleFactory.java @@ -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 * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,7 +8,6 @@ * Contributors: * Markus Schorn - initial API and implementation *******************************************************************************/ - package org.eclipse.cdt.internal.core.model.ext; 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.ICPPClassTemplate; 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.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope; @@ -68,7 +68,14 @@ public class CElementHandleFactory { 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()); if (parentElement == null) { return null; 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 0358063b763..37d0f323284 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 @@ -1,13 +1,14 @@ /******************************************************************************* - * 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 * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * IBM - Initial API and implementation - * Bryan Wilkinson (QNX) + * IBM - Initial API and implementation + * Bryan Wilkinson (QNX) + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -80,13 +81,13 @@ public class CPPASTUsingDeclaration extends CPPASTNode implements public int getRoleForName(IASTName n) { if( n == name ) - return r_reference; + return r_definition; return r_unclear; } public IBinding[] findBindings(IASTName n, boolean isPrefix) { IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix); - List filtered = new ArrayList(); + List filtered = new ArrayList(); for (int i = 0;i < bindings.length; i++) { 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()]); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDelegate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDelegate.java index e1218f25e57..ca5c2ac9ff1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDelegate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDelegate.java @@ -113,6 +113,9 @@ public class CPPDelegate extends PlatformObject implements ICPPDelegate, ICPPInt * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#getDefinition() */ public IASTNode getDefinition() { + if (usingDeclaration instanceof ICPPInternalBinding) { + return ((ICPPInternalBinding) usingDeclaration).getDefinition(); + } return null; } @@ -153,4 +156,8 @@ public class CPPDelegate extends PlatformObject implements ICPPDelegate, ICPPInt public ILinkage getLinkage() { return Linkage.CPP_LINKAGE; } + + public ICPPUsingDeclaration getUsingDeclaration() { + return usingDeclaration; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java index be4f31704a4..a7b9358eb61 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java @@ -10,7 +10,6 @@ * Markus Schorn (Wind River Systems) * Andrew Ferguson (Symbian) *******************************************************************************/ - package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.IName; @@ -1105,7 +1104,7 @@ public class CPPVisitor { public static class CollectDeclarationsAction extends CPPASTVisitor { private static final int DEFAULT_LIST_SIZE = 8; private IASTName [] decls; - private IBinding binding; + private IBinding[] bindings; private int idx = 0; private int kind; @@ -1118,11 +1117,23 @@ public class CPPVisitor { public CollectDeclarationsAction( IBinding binding ){ - this.binding = binding; + shouldVisitNames = true; this.decls = new IASTName[ DEFAULT_LIST_SIZE ]; - shouldVisitNames = true; - if( binding instanceof ILabel ) + this.bindings = new IBinding[] {binding}; + 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; else if( binding instanceof ICPPTemplateParameter ) kind = KIND_TEMPLATE_PARAMETER; @@ -1135,8 +1146,6 @@ public class CPPVisitor { else if( binding instanceof ICPPNamespace) { kind = KIND_NAMESPACE; } - else if( binding instanceof ICPPUsingDeclaration ) - kind = KIND_COMPOSITE; else kind = KIND_OBJ_FN; } @@ -1212,64 +1221,40 @@ public class CPPVisitor { return PROCESS_CONTINUE; } - if( binding != null ) - { - 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 ){ - IASTName [] temp = new IASTName[ decls.length * 2 ]; - System.arraycopy( decls, 0, temp, 0, decls.length ); - decls = temp; - } - decls[idx++] = name; - } - if( n > -1 && ++n < bs.length ){ - candidate = bs[n]; - } else break; + if( bindings != null ) { + if (isDeclarationsBinding(name.resolveBinding())) { + if( decls.length == idx ){ + IASTName [] temp = new IASTName[ decls.length * 2 ]; + System.arraycopy( decls, 0, temp, 0, decls.length ); + decls = temp; + } + decls[idx++] = name; } } 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(){ if( idx < decls.length ){ 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 { private static final int DEFAULT_LIST_SIZE = 8; private IASTName [] refs; - private IBinding binding; + private IBinding[] bindings; private int idx = 0; private int kind; @@ -1295,28 +1299,35 @@ public class CPPVisitor { public CollectReferencesAction( IBinding binding ){ - if (binding instanceof ICPPSpecialization) { - binding= ((ICPPSpecialization) binding).getSpecializedBinding(); - } - this.binding = binding; + shouldVisitNames = true; this.refs = new IASTName[ DEFAULT_LIST_SIZE ]; + + binding = unwindBinding(binding); + this.bindings = new IBinding[] {binding}; - shouldVisitNames = true; - if( binding instanceof ILabel ) + if (binding instanceof ICPPUsingDeclaration) { + try { + ICPPDelegate[] delegates= ((ICPPUsingDeclaration) binding).getDelegates(); + this.bindings= new IBinding[delegates.length]; + for (int i = 0; i < delegates.length; i++) { + binding= this.bindings[i]= delegates[i].getBinding(); + } + } catch (DOMException e) { + } + kind= KIND_COMPOSITE; + } else if( binding instanceof ILabel ) { kind = KIND_LABEL; - else if( binding instanceof ICompositeType || + } else if( binding instanceof ICompositeType || binding instanceof ITypedef || - binding instanceof IEnumeration) - { + binding instanceof IEnumeration) { kind = KIND_TYPE; - } - else if( binding instanceof ICPPNamespace) { + } else if( binding instanceof ICPPNamespace) { kind = KIND_NAMESPACE; - } else if( binding instanceof ICPPUsingDeclaration || - binding instanceof ICPPTemplateParameter ) + } else if( binding instanceof ICPPTemplateParameter ) { kind = KIND_COMPOSITE; - else + } else { kind = KIND_OBJ_FN; + } } public int visit( IASTName name ){ @@ -1382,63 +1393,46 @@ public class CPPVisitor { return PROCESS_CONTINUE; } - if( binding != null ){ - 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 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 ]; - System.arraycopy( refs, 0, temp, 0, refs.length ); - refs = temp; - } - refs[idx++] = name; - break; - } - if( n > -1 && ++n < bs.length ){ - candidate = bs[n]; - } else break; + if( bindings != null ){ + if (isReferenceBinding(name.resolveBinding())) { + if (refs.length == idx){ + IASTName [] temp = new IASTName[ refs.length * 2 ]; + System.arraycopy( refs, 0, temp, 0, refs.length ); + refs = temp; + } + refs[idx++] = name; } } return PROCESS_CONTINUE; } - private boolean sameBinding(IBinding binding1, IBinding binding2) { - if (binding1 == binding2) - return true; - if (binding1.equals(binding2)) - return true; + + 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; + } + } + 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; + } + } + } catch (DOMException e) { + } + return false; + } else { + return false; + } + } return false; } + public IASTName[] getReferences(){ if( idx < refs.length ){ IASTName [] temp = new IASTName[ idx ]; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java index 4de0e3cc80e..62d0dc7c4ed 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CIndex.java @@ -11,7 +11,6 @@ * Andrew Ferguson (Symbian) * Anton Leherbauer (Wind River Systems) *******************************************************************************/ - package org.eclipse.cdt.internal.core.index; 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.IASTName; 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.index.IIndex; 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.IndexFilter; 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.ICompositesFactory; 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 { + LinkedList result= new LinkedList(); if (binding instanceof ICPPUsingDeclaration) { - IBinding[] bindings= null; + ICPPDelegate[] bindings= null; try { bindings = ((ICPPUsingDeclaration)binding).getDelegates(); } catch (DOMException e) { @@ -133,16 +135,26 @@ public class CIndex implements IIndex { return new IIndexName[0]; } if (bindings.length > 1) { - ArrayList result= new ArrayList(); + ArrayList multi= new ArrayList(); for (int i = 0; i < bindings.length; 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]; + } 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 result= new LinkedList(); + int fragCount= 0; for (int i = 0; i < fPrimaryFragmentCount; i++) { final IIndexFragmentName[] names = fFragments[i].findNames(binding, flags); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java index 0a7dbff881b..4925c795ef8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java @@ -11,7 +11,6 @@ * IBM Corporation * Andrew Ferguson (Symbian) *******************************************************************************/ - package org.eclipse.cdt.internal.core.pdom.dom; 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.ICPPDeferredTemplateInstance; 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.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; @@ -261,8 +259,12 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage } else { // 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) - while (binding instanceof ICPPDelegate && !(binding instanceof ICPPNamespaceAlias)) { - binding= ((ICPPDelegate) binding).getBinding(); + while (binding instanceof ICPPDelegate) { + final ICPPDelegate delegate = (ICPPDelegate)binding; + if (delegate.getDelegateType() != ICPPDelegate.USING_DECLARATION) { + break; + } + binding= delegate.getBinding(); } IScope scope = binding.getScope(); if (scope == null) { @@ -356,17 +358,19 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage if (binding instanceof IField) { return null; } - boolean isFileLocal= false; + boolean checkInSourceOnly= false; if (binding instanceof IVariable) { if (!(binding instanceof IField)) { - isFileLocal= ASTInternal.isStatic((IVariable) binding); + checkInSourceOnly= ASTInternal.isStatic((IVariable) binding); } } else if (binding instanceof IFunction) { 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); if (path != null) { return wpdom.getFileForASTPath(getLinkageID(), path); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMName.java index 1cb54f1330f..a8610be992e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMName.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMName.java @@ -17,7 +17,6 @@ import java.util.ArrayList; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.IASTFileLocation; 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.IIndexName; import org.eclipse.cdt.internal.core.index.IIndexFragment; @@ -105,11 +104,6 @@ public final class PDOMName implements IIndexFragmentName, IASTFileLocation { if (name.isDeclaration()) { 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; } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CPPSelectionTestsNoIndexer.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CPPSelectionTestsNoIndexer.java index a164b433b4e..245a43909e4 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CPPSelectionTestsNoIndexer.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CPPSelectionTestsNoIndexer.java @@ -1,13 +1,13 @@ /******************************************************************************* - * 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 * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * IBM - Initial API and implementation - * Markus Schorn (Wind River Systems) + * IBM - Initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.ui.tests.text.selection; @@ -80,7 +80,12 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase { static ICProject cPrj; static FileManager fileManager; static boolean disabledHelpContributions = false; - { + + static void initProject() { + if (project != null) { + return; + } + //(CCorePlugin.getDefault().getCoreModel().getIndexManager()).reset(); monitor = new NullProgressMonitor(); @@ -126,14 +131,19 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase { closeAllEditors(); try{ project.delete( true, false, monitor ); - project = null; - } catch( Throwable e ){ - /*boo*/ + } catch( CoreException e ){ + try { + project.delete( true, false, monitor ); + } + catch (CoreException e1) {} + } finally { + project= null; } } protected void setUp() throws Exception { super.setUp(); + initProject(); OpenDeclarationsAction.sIsJUnitTest= true; } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CSelectionTestsNoIndexer.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CSelectionTestsNoIndexer.java index ee6b7ccf95d..a08bdf1b6ae 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CSelectionTestsNoIndexer.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CSelectionTestsNoIndexer.java @@ -1,13 +1,13 @@ /******************************************************************************* - * 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 * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * IBM - Initial API and implementation - * Markus Schorn (Wind River Systems) + * IBM - Initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.ui.tests.text.selection; @@ -75,7 +75,11 @@ public class CSelectionTestsNoIndexer extends BaseUITestCase { static ICProject cPrj; static FileManager fileManager; static boolean disabledHelpContributions = false; - { + + void initProject() { + if (project != null) { + return; + } //(CCorePlugin.getDefault().getCoreModel().getIndexManager()).reset(); monitor = new NullProgressMonitor(); @@ -114,12 +118,18 @@ public class CSelectionTestsNoIndexer extends BaseUITestCase { protected void setUp() throws Exception { super.setUp(); OpenDeclarationsAction.sIsJUnitTest= true; + initProject(); } public void cleanupProject() throws Exception { - closeAllEditors(); - CProjectHelper.delete(cPrj); - project= null; + try { + closeAllEditors(); + CProjectHelper.delete(cPrj); + project= null; + } + finally { + project= null; + } } protected void tearDown() throws Exception { diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsAction.java index ef6f8327f83..f364932a971 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsAction.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsAction.java @@ -10,7 +10,6 @@ * Markus Schorn (Wind River Systems) * Ed Swartz (Nokia) *******************************************************************************/ - package org.eclipse.cdt.internal.ui.search.actions; 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.cpp.ICPPMethod; 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.IIndexManager; import org.eclipse.cdt.core.index.IIndexName; @@ -81,6 +81,10 @@ public class OpenDeclarationsAction extends SelectionParseAction { } 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 IIndex fIndex; @@ -132,16 +136,23 @@ public class OpenDeclarationsAction extends SelectionParseAction { openInclude(((IASTPreprocessorIncludeStatement) parent)); return Status.OK_STATUS; } - boolean isDefinition= searchName.isDefinition(); IBinding binding = searchName.resolveBinding(); 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 (binding instanceof ICPPSpecialization) { // bug 207320, handle template instances IBinding specialized= ((ICPPSpecialization) binding).getSpecializedBinding(); if (specialized != null && !(specialized instanceof IProblemBinding)) { - declNames = findNames(fIndex, ast, true, specialized); + declNames = findNames(fIndex, ast, KIND_DEFINITION, specialized); } } else if (binding instanceof ICPPMethod) { // bug 86829, handle implicit methods. @@ -150,7 +161,7 @@ public class OpenDeclarationsAction extends SelectionParseAction { try { IBinding clsBinding= method.getClassOwner(); if (clsBinding != null && !(clsBinding instanceof IProblemBinding)) { - declNames= findNames(fIndex, ast, false, clsBinding); + declNames= findNames(fIndex, ast, KIND_OTHER, clsBinding); } } catch (DOMException e) { // don't log problem bindings. @@ -239,7 +250,7 @@ public class OpenDeclarationsAction extends SelectionParseAction { } private boolean navigateViaCElements(ICProject project, IIndex index, IName[] declNames) { - final ArrayList elements= new ArrayList(); + final ArrayList elements= new ArrayList(); for (int i = 0; i < declNames.length; i++) { try { ICElement elem = getCElementForName(project, index, declNames[i]); @@ -264,7 +275,7 @@ public class OpenDeclarationsAction extends SelectionParseAction { if (sIsJUnitTest) { 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(), CEditorMessages.getString("OpenDeclarationsAction.dialog.title"), CEditorMessages.getString("OpenDeclarationsAction.selectMessage"), //$NON-NLS-1$ //$NON-NLS-2$ CElementBaseLabels.ALL_DEFAULT | CElementBaseLabels.MF_POST_FILE_QUALIFIED, 0); @@ -307,28 +318,64 @@ public class OpenDeclarationsAction extends SelectionParseAction { return null; } - private IName[] findNames(IIndex index, IASTTranslationUnit ast, - boolean isDefinition, IBinding binding) throws CoreException { - IName[] declNames= isDefinition ? - findDeclarations(index, ast, binding) : - findDefinitions(index, ast, binding); + private IName[] findNames(IIndex index, IASTTranslationUnit ast, int isKind, IBinding binding) throws CoreException { + IName[] declNames; + if (isKind == KIND_DEFINITION) { + declNames= findDeclarations(index, ast, binding); + } else { + declNames= findDefinitions(index, ast, isKind, binding); + } if (declNames.length == 0) { - declNames= isDefinition ? - findDefinitions(index, ast, binding) : - findDeclarations(index, ast, binding); + if (isKind == KIND_DEFINITION) { + declNames= findDefinitions(index, ast, isKind, binding); + } else { + declNames= findDeclarations(index, ast, binding); + } } return declNames; } - private IName[] findDefinitions(IIndex index, IASTTranslationUnit ast, - IBinding binding) throws CoreException { - IName[] declNames= ast.getDefinitionsInAST(binding); - if (declNames.length == 0) { - // 2. Try definition in index - declNames = index.findNames(binding, IIndex.FIND_DEFINITIONS | IIndex.SEARCH_ACCROSS_LANGUAGE_BOUNDARIES); + private IName[] findDefinitions(IIndex index, IASTTranslationUnit ast, int isKind, IBinding binding) throws CoreException { + IASTName[] declNames= ast.getDefinitionsInAST(binding); + boolean containsUsingDirectives= false; + for (int i = 0; i < declNames.length; i++) { + IASTName name= declNames[i]; + if (name.resolveBinding() instanceof ICPPUsingDeclaration) { + containsUsingDirectives= true; + break; + } } - return declNames; + 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 + 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 inames; + } + + private IASTName[] separateUsingDecls(IASTName[] declNames, boolean keep) { + ArrayList result= new ArrayList(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, -- cgit v1.2.3