diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/prefix/BasicCompletionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/prefix/BasicCompletionTest.java index f7b43f171b2..c1954d415f8 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/prefix/BasicCompletionTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/prefix/BasicCompletionTest.java @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (c) 2004, 2005 IBM Corporation and others. + * Copyright (c) 2004, 2007 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 @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Bryan Wilkinson (QNX) *******************************************************************************/ package org.eclipse.cdt.core.parser.tests.prefix; @@ -54,9 +55,8 @@ public class BasicCompletionTest extends CompletionTestBase { assertEquals("func2", ((IFunction)bindings[1]).getName()); // The second name shouldn't be hooked up assertNull(names[1].getTranslationUnit()); - // The declaration should point to nothing since there are no types - bindings = names[2].resolvePrefix(); - assertEquals(0, bindings.length); + // The third name shouldn't be hooked up either + assertNull(names[2].getTranslationUnit()); // C node = getGCCCompletionNode(code.toString()); @@ -69,9 +69,8 @@ public class BasicCompletionTest extends CompletionTestBase { assertEquals(2, bindings.length); assertEquals("func", ((IFunction)bindings[0]).getName()); assertEquals("func2", ((IFunction)bindings[1]).getName()); - // The declaration should point to nothing since there are no types - bindings = names[1].resolvePrefix(); - assertEquals(0, bindings.length); + // The second name shouldn't be hooked up + assertNull(names[1].getTranslationUnit()); } public void testTypedef() throws Exception { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IScope.java index 3879ab514a9..42bdbf20fac 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IScope.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2006 IBM Corporation and others. + * Copyright (c) 2004, 2007 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 @@ -8,6 +8,7 @@ * Contributors: * IBM - Initial API and implementation * Markus Schorn (Wind River Systems) + * Bryan Wilkinson (QNX) *******************************************************************************/ package org.eclipse.cdt.core.dom.ast; @@ -46,6 +47,18 @@ public interface IScope { */ public IBinding[] find(String name) throws DOMException; + /** + * This is the general lookup entry point. It returns the list of + * valid bindings for a given name or prefix. The lookup proceeds as an unqualified + * lookup. Constructors are not considered during this lookup and won't be returned. + * No attempt is made to resolve potential ambiguities or perform access checking. + * + * @param name the name for which to search + * @param prefixLookup whether or not to only check prefixes + * @return List of IBinding + */ + public IBinding[] find(String name, boolean prefixLookup) throws DOMException; + /** * Get the binding in this scope that the given name would resolve to. Could * return null if there is no matching binding in this scope, if the binding has not diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/GCCLanguage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/GCCLanguage.java index 02dae7676cf..b9121f83ddc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/GCCLanguage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/GCCLanguage.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2006 QNX Software Systems and others. + * Copyright (c) 2005, 2007 QNX Software Systems 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 @@ -97,7 +97,8 @@ public class GCCLanguage extends AbstractLanguage { scanner, ParserMode.COMPLETION_PARSE, ParserUtil.getParserLogService(), - new GCCParserExtensionConfiguration()); + new GCCParserExtensionConfiguration(), + index); // Run the parse and return the completion node parser.parse(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/GPPLanguage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/GPPLanguage.java index 6bf99064789..b7c3b102fda 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/GPPLanguage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/GPPLanguage.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2006 QNX Software Systems and others. + * Copyright (c) 2005, 2007 QNX Software Systems 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 @@ -97,7 +97,8 @@ public class GPPLanguage extends AbstractLanguage { scanner, ParserMode.COMPLETION_PARSE, ParserUtil.getParserLogService(), - new GPPParserExtensionConfiguration()); + new GPPParserExtensionConfiguration(), + index); // Run the parse and return the completion node parser.parse(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java index ff2336f41ff..a0d6ee8f6e5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 2007 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,6 +8,7 @@ * Contributors: * Markus Schorn - initial API and implementation * Andrew Ferguson (Symbian) + * Bryan Wilkinson (QNX) *******************************************************************************/ package org.eclipse.cdt.core.index; @@ -241,6 +242,15 @@ public interface IIndex { */ public IBinding[] findInNamespace(IBinding nsbinding, char[] name); + /** + * Searches for all bindings with names that start with the given prefix. + * @param prefix the prefix with which all returned bindings must start + * @param filter a filter that allows for skipping parts of the index + * @return an array of bindings with the prefix + * @throws CoreException + */ + public IBinding[] findBindingsForPrefix(String prefix, IndexFilter filter) throws CoreException; + /** * Searches for all names that resolve to the given binding. You can limit the result to references, declarations * or definitions, or a combination of those. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IndexFilter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IndexFilter.java index 20dddfdb8ef..ab8897db1bc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IndexFilter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IndexFilter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 2007 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,11 +8,13 @@ * Contributors: * Markus Schorn - initial API and implementation * Andrew Ferguson (Symbian) + * Bryan Wilkinson (QNX) *******************************************************************************/ package org.eclipse.cdt.core.index; import org.eclipse.cdt.core.dom.ILinkage; +import org.eclipse.cdt.core.dom.ast.IBinding; /** * Can be subclassed and used for queries in the index. @@ -61,4 +63,14 @@ public class IndexFilter { public boolean acceptImplicitMethods() { return false; } + + /** + * Determines whether or not a binding is valid. + * + * @param binding the binding being checked for validity + * @return whether or not the binding is valid + */ + public boolean acceptBinding(IBinding binding) { + return true; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTCompletionContext.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTCompletionContext.java new file mode 100644 index 00000000000..28fafdce7c0 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTCompletionContext.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2007 QNX Software Systems 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: + * QNX - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.core.dom.parser; + +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IBinding; + +/** + * Interface for a code completion's context. Used for context-sensitive + * finding of bindings with a certain prefix. + * + *
+ * This interface is not intended to be implemented by clients. + *
+ *+ * EXPERIMENTAL. This class or interface has been added as + * part of a work in progress. There is no guarantee that this API will work or + * that it will remain the same. Please do not use this API without consulting + * with the CDT team. + *
+ * + * @author Bryan Wilkinson + * @since 4.0 + */ +public interface IASTCompletionContext { + + /** + * Returns bindings that start with the given prefix, only considering those + * that are valid for this context. + * + * @param n the name containing a prefix + * @return valid bindings in this context for the given prefix + */ + IBinding[] resolvePrefix(IASTName n); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java index ff020287f5e..d3c6aaf653a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2006 IBM Corporation and others. + * Copyright (c) 2004, 2007 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 @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Markus Schorn (Wind River Systems) + * Bryan Wilkinson (QNX) *******************************************************************************/ /* @@ -134,13 +135,19 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I throw new DOMException( this ); } - /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String) */ public IBinding[] find( String name ) throws DOMException { throw new DOMException( this ); } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String) + */ + public IBinding[] find( String name, boolean prefixLookup ) throws DOMException { + throw new DOMException( this ); + } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IScope#getScopeName() diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFieldReference.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFieldReference.java index 7f91f53a1f9..4f6d91e2469 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFieldReference.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFieldReference.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2006 IBM Corporation and others. + * Copyright (c) 2005, 2007 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 @@ -8,21 +8,32 @@ * Contributors: * IBM Rational Software - Initial API and implementation * Yuan Zhang / Beth Tibbitts (IBM Research) + * Bryan Wilkinson (QNX) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.c; +import java.util.ArrayList; +import java.util.List; + import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTFieldReference; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.ICompositeType; +import org.eclipse.cdt.core.dom.ast.IField; import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; +import org.eclipse.cdt.internal.core.dom.parser.IASTCompletionContext; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPSemantics; /** * @author jcamelon */ -public class CASTFieldReference extends CASTNode implements IASTFieldReference, IASTAmbiguityParent { +public class CASTFieldReference extends CASTNode implements IASTFieldReference, IASTAmbiguityParent, IASTCompletionContext { private IASTExpression owner; private IASTName name; @@ -92,5 +103,31 @@ public class CASTFieldReference extends CASTNode implements IASTFieldReference, public IType getExpressionType() { return CVisitor.getExpressionType(this); } - + + public IBinding[] resolvePrefix(IASTName n) { + IASTExpression expression = getFieldOwner(); + IType type = expression.getExpressionType(); + type = CPPSemantics.getUltimateType(type, true); //stop at pointer to member? + + if (type instanceof ICompositeType) { + ICompositeType compType = (ICompositeType) type; + List bindings = new ArrayList(); + char[] name = n.toCharArray(); + + try { + IField[] fields = compType.getFields(); + for (int i = 0; i < fields.length; i++) { + char[] potential = fields[i].getNameCharArray(); + if (CharArrayUtils.equals(potential, 0, name.length, name, false)) { + bindings.add(fields[i]); + } + } + } catch (DOMException e) { + } + + return (IBinding[]) bindings.toArray(new IBinding[bindings.size()]); + } + + return null; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTIdExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTIdExpression.java index 5acdedbb94e..c7f4905d8d9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTIdExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTIdExpression.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2006 IBM Corporation and others. + * Copyright (c) 2005, 2007 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 @@ -8,18 +8,28 @@ * Contributors: * IBM Rational Software - Initial API and implementation * Yuan Zhang / Beth Tibbitts (IBM Research) + * Bryan Wilkinson (QNX) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.c; import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.index.IIndex; +import org.eclipse.cdt.core.index.IndexFilter; +import org.eclipse.cdt.core.parser.util.ArrayUtil; +import org.eclipse.cdt.internal.core.dom.Linkage; +import org.eclipse.cdt.internal.core.dom.parser.IASTCompletionContext; +import org.eclipse.core.runtime.CoreException; /** * @author jcamelon */ -public class CASTIdExpression extends CASTNode implements IASTIdExpression { +public class CASTIdExpression extends CASTNode implements IASTIdExpression, IASTCompletionContext { private IASTName name; @@ -61,4 +71,33 @@ public class CASTIdExpression extends CASTNode implements IASTIdExpression { return CVisitor.getExpressionType(this); } + public IBinding[] resolvePrefix(IASTName n) { + IScope scope = CVisitor.getContainingScope(n); + + IBinding[] b1 = null; + if (scope != null) { + try { + b1 = scope.find(n.toString(), true); + } catch (DOMException e) { + } + } + + IIndex index = getTranslationUnit().getIndex(); + + IBinding[] b2 = null; + if (index != null) { + try { + b2 = index.findBindingsForPrefix( + n.toString(), + IndexFilter.getFilter(Linkage.C_LINKAGE)); + } catch (CoreException e) { + } + } + + int size = (b1 == null ? 0 : b1.length) + (b2 == null ? 0 : b2.length); + IBinding[] all = new IBinding[size]; + if (b1 != null) ArrayUtil.addAll(IBinding.class, all, b1); + if (b2 != null) ArrayUtil.addAll(IBinding.class, all, b2); + return all; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTName.java index 857607b21a8..c4cfdc1a241 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTName.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTName.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2006 IBM Corporation and others. + * Copyright (c) 2005, 2007 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 @@ -9,6 +9,7 @@ * IBM Rational Software - Initial API and implementation * Markus Schorn (Wind River Systems) * Yuan Zhang / Beth Tibbitts (IBM Research) + * Bryan Wilkinson (QNX) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.c; @@ -19,6 +20,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNameOwner; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.internal.core.dom.Linkage; +import org.eclipse.cdt.internal.core.dom.parser.IASTCompletionContext; /** * @author jcamelon @@ -56,7 +58,16 @@ public class CASTName extends CASTNode implements IASTName { } public IBinding[] resolvePrefix() { - return CVisitor.prefixLookup(this); + IASTNode node = getParent(); + while (!(node instanceof IASTCompletionContext)) { + if (node == null) { + return null; + } + node = node.getParent(); + } + + IASTCompletionContext context = (IASTCompletionContext) node; + return context.resolvePrefix(this); } public void setBinding(IBinding binding) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTypedefNameSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTypedefNameSpecifier.java index e39382da670..697819c5da5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTypedefNameSpecifier.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTypedefNameSpecifier.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2006 IBM Corporation and others. + * Copyright (c) 2005, 2007 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 @@ -8,18 +8,33 @@ * Contributors: * IBM Rational Software - Initial API and implementation * Yuan Zhang / Beth Tibbitts (IBM Research) + * Bryan Wilkinson (QNX) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.c; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ast.ASTVisitor; +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.ICompositeType; +import org.eclipse.cdt.core.dom.ast.IEnumeration; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.c.ICASTTypedefNameSpecifier; +import org.eclipse.cdt.core.index.IIndex; +import org.eclipse.cdt.core.index.IndexFilter; +import org.eclipse.cdt.internal.core.dom.parser.IASTCompletionContext; +import org.eclipse.core.runtime.CoreException; /** * @author jcamelon */ public class CASTTypedefNameSpecifier extends CASTBaseDeclSpecifier implements - ICASTTypedefNameSpecifier { + ICASTTypedefNameSpecifier, IASTCompletionContext { private IASTName name; /* (non-Javadoc) @@ -63,4 +78,47 @@ public class CASTTypedefNameSpecifier extends CASTBaseDeclSpecifier implements return r_unclear; } + public IBinding[] resolvePrefix(IASTName n) { + List filtered = new ArrayList(); + IndexFilter filter = new IndexFilter() { + public boolean acceptBinding(IBinding binding) { + return binding instanceof ICompositeType + || binding instanceof IEnumeration + || binding instanceof ITypedef; + } + public boolean acceptLinkage(ILinkage linkage) { + return linkage.getID() == ILinkage.C_LINKAGE_ID; + } + }; + + IScope scope = CVisitor.getContainingScope(n); + + if (scope == null) { + scope = getTranslationUnit().getScope(); + } + + try { + IBinding[] bindings = scope.find(n.toString(), true); + for (int i = 0 ; i < bindings.length; i++) { + if (filter.acceptBinding(bindings[i])) { + filtered.add(bindings[i]); + } + } + } catch (DOMException e) { + } + + IIndex index = getTranslationUnit().getIndex(); + + if (index != null) { + try { + IBinding[] bindings = index.findBindingsForPrefix(n.toString(), filter); + for (int i = 0; i < bindings.length; i++) { + filtered.add(bindings[i]); + } + } catch (CoreException e) { + } + } + + return (IBinding[]) filtered.toArray(new IBinding[filtered.size()]); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CScope.java index 6127b582bc8..1a4aebf3e69 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CScope.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2006 IBM Corporation and others. + * Copyright (c) 2004, 2007 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 @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Markus Schorn (Wind River Systems) + * Bryan Wilkinson (QNX) *******************************************************************************/ /* @@ -95,11 +96,19 @@ public class CScope implements ICScope, IASTInternalScope { return (IASTName[]) ArrayUtil.trim( IASTName.class, result ); } } + /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String) */ public IBinding[] find( String name ) throws DOMException { - return CVisitor.findBindings( this, name ); + return CVisitor.findBindings( this, name, false ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String) + */ + public IBinding[] find( String name, boolean prefixLookup ) throws DOMException { + return CVisitor.findBindings( this, name, prefixLookup ); } public IBinding getBinding( int namespaceType, char [] name ){ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java index e44c9e73487..137b83508ef 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2006 IBM Corporation and others. + * Copyright (c) 2005, 2007 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 @@ -8,10 +8,14 @@ * Contributors: * IBM Rational Software - Initial API and implementation * Markus Schorn (Wind River Systems) + * Bryan Wilkinson (QNX) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.c; +import java.util.ArrayList; +import java.util.List; + import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; import org.eclipse.cdt.core.dom.ast.DOMException; @@ -609,7 +613,7 @@ public class CVisitor { char [] p = fieldReference.getFieldName().toCharArray(); IField [] fields = ((ICompositeType) type).getFields(); for ( int i = 0; i < fields.length; i++ ) { - if( CharArrayUtils.equals( fields[i].getNameCharArray(), 0, p.length, p ) ){ + if( CharArrayUtils.equals( fields[i].getNameCharArray(), 0, p.length, p, false ) ){ result = (IBinding[]) ArrayUtil.append( IBinding.class, result, fields[i] ); } } @@ -1415,7 +1419,7 @@ public class CVisitor { char [] c = candidate.toCharArray(); if( prefixMap == null && CharArrayUtils.equals( c, name ) ){ return candidate; - } else if( prefixMap != null && CharArrayUtils.equals( c, 0, name.length, name ) && !prefixMap.containsKey( c ) ){ + } else if( prefixMap != null && CharArrayUtils.equals( c, 0, name.length, name, false ) && !prefixMap.containsKey( c ) ){ prefixMap.put( c, candidate ); } return prefixMap; @@ -1437,7 +1441,7 @@ public class CVisitor { char [] n = name.toCharArray(); if( prefixMap == null && CharArrayUtils.equals( c, n ) ) return tempName; - else if( prefixMap != null && CharArrayUtils.equals( c, 0, n.length, n ) && !prefixMap.containsKey( c ) ) + else if( prefixMap != null && CharArrayUtils.equals( c, 0, n.length, n, false ) && !prefixMap.containsKey( c ) ) prefixMap.put( c, tempName ); } else { return checkForBinding( scope, paramDecl.getDeclSpecifier(), name, typesOnly, prefixMap ); @@ -1920,7 +1924,7 @@ public class CVisitor { return (IBinding[]) ArrayUtil.trim( IBinding.class, result ); } - public static IBinding[] findBindings( IScope scope, String name ) throws DOMException{ + public static IBinding[] findBindings( IScope scope, String name, boolean prefixLookup ) throws DOMException{ IASTNode node = ASTInternal.getPhysicalNodeOfScope(scope); if( node instanceof IASTFunctionDefinition ) node = ((IASTFunctionDefinition)node).getBody(); @@ -1930,39 +1934,65 @@ public class CVisitor { //normal names astName.setPropertyInParent( STRING_LOOKUP_PROPERTY ); - IBinding b1 = (IBinding) findBinding( astName, astName, COMPLETE ); + int flags = prefixLookup ? COMPLETE | PREFIX_LOOKUP : COMPLETE; + Object o1 = findBinding( astName, astName, flags ); + IBinding[] b1 = null; + if (o1 instanceof IBinding) { + b1 = new IBinding[] { (IBinding) o1 }; + } else { + b1 = (IBinding[]) o1; + } + //structure names astName.setPropertyInParent( STRING_LOOKUP_TAGS_PROPERTY ); - IBinding b2 = (IBinding) findBinding( astName, astName, COMPLETE | TAGS ); + flags = prefixLookup ? COMPLETE | TAGS | PREFIX_LOOKUP : COMPLETE | TAGS; + Object o2 = findBinding( astName, astName, flags ); + IBinding[] b2 = null; + if (o2 instanceof IBinding) { + b2 = new IBinding[] { (IBinding) o2 }; + } else { + b2 = (IBinding[]) o2; + } + //label names - ILabel b3 = null; + List b3 = new ArrayList(); do{ char [] n = name.toCharArray(); if( scope instanceof ICFunctionScope ){ ILabel [] labels = ((CFunctionScope)scope).getLabels(); for( int i = 0; i < labels.length; i++ ){ ILabel label = labels[i]; - if( CharArrayUtils.equals( label.getNameCharArray(), n) ){ - b3 = label; - break; + if (prefixLookup) { + if (CharArrayUtils.equals(label.getNameCharArray(), + 0, n.length, n, false)) { + b3.add(label); + } + } else { + if (CharArrayUtils.equals(label.getNameCharArray(), n)) { + b3.add(label); + break; + } } } - break; + if (!prefixLookup) break; } scope = scope.getParent(); } while( scope != null ); - int c = (( b1 != null ) ? 1 : 0) + (( b2 != null ) ? 1 : 0) + (( b3 != null ) ? 1 : 0); + int c = (b1 == null ? 0 : b1.length) + (b2 == null ? 0 :b2.length) + (b3 == null ? 0 : b3.size()); + IBinding [] result = new IBinding [c]; - c = 0; - if( b1 != null ) - result[c++] = b1; - if( b2 != null ) - result[c++] = b2; - if( b3 != null ) - result[c] = b3; + + if (b1 != null) + ArrayUtil.addAll(IBinding.class, result, b1); + + if (b2 != null) + ArrayUtil.addAll(IBinding.class, result, b2); + + if (b3 != null) + ArrayUtil.addAll(IBinding.class, result, b3.toArray(new IBinding[b3.size()])); return result; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBaseSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBaseSpecifier.java index 6f83737684e..96425c01600 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBaseSpecifier.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBaseSpecifier.java @@ -7,19 +7,32 @@ * * Contributors: * IBM - Initial API and implementation + * Bryan Wilkinson (QNX) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ast.ASTVisitor; +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.IScope; import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; +import org.eclipse.cdt.core.index.IIndex; +import org.eclipse.cdt.core.index.IndexFilter; +import org.eclipse.cdt.internal.core.dom.parser.IASTCompletionContext; +import org.eclipse.core.runtime.CoreException; /** * @author jcamelon */ public class CPPASTBaseSpecifier extends CPPASTNode implements - ICPPASTBaseSpecifier { + ICPPASTBaseSpecifier, IASTCompletionContext { private boolean isVirtual; private int visibility; @@ -98,4 +111,53 @@ public class CPPASTBaseSpecifier extends CPPASTNode implements return r_unclear; } + public IBinding[] resolvePrefix(IASTName n) { + List filtered = new ArrayList(); + IndexFilter filter = new IndexFilter(){ + public boolean acceptBinding(IBinding binding) { + if (binding instanceof ICPPClassType) { + ICPPClassType classType = (ICPPClassType) binding; + try { + int key = classType.getKey(); + if (key == ICPPClassType.k_class) { + return true; + } + } catch (DOMException e) { + } + } + return false; + } + public boolean acceptLinkage(ILinkage linkage) { + return linkage.getID() == ILinkage.CPP_LINKAGE_ID; + } + }; + + IScope scope = CPPVisitor.getContainingScope(n); + + if (scope != null) { + try { + IBinding[] bindings = scope.find(n.toString(), true); + for (int i = 0; i < bindings.length; i++) { + if (filter.acceptBinding(bindings[i])) { + filtered.add(bindings[i]); + } + } + } catch (DOMException e) { + } + } + + IIndex index = getTranslationUnit().getIndex(); + + if (index != null) { + try { + IBinding[] bindings = index.findBindingsForPrefix(n.toString(), filter); + for (int i = 0; i < bindings.length; i++) { + filtered.add(bindings[i]); + } + } catch (CoreException e) { + } + } + + return (IBinding[]) filtered.toArray(new IBinding[filtered.size()]); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java index e2b4ebcf334..c0e624f1ad6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java @@ -7,22 +7,35 @@ * * Contributors: * IBM - Initial API and implementation + * Bryan Wilkinson (QNX) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import java.util.ArrayList; +import java.util.List; + import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IField; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; +import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; +import org.eclipse.cdt.internal.core.dom.parser.IASTCompletionContext; /** * @author jcamelon */ public class CPPASTFieldReference extends CPPASTNode implements - ICPPASTFieldReference, IASTAmbiguityParent { + ICPPASTFieldReference, IASTAmbiguityParent, IASTCompletionContext { private boolean isTemplate; private IASTExpression owner; @@ -101,5 +114,64 @@ public class CPPASTFieldReference extends CPPASTNode implements public IType getExpressionType() { return CPPVisitor.getExpressionType(this); } + + public IBinding[] resolvePrefix(IASTName n) { + IASTExpression expression = getFieldOwner(); + IType type = expression.getExpressionType(); + type = CPPSemantics.getUltimateType(type, true); //stop at pointer to member? + + if (type instanceof ICPPClassType) { + ICPPClassType classType = (ICPPClassType) type; + List bindings = new ArrayList(); + char[] name = n.toCharArray(); + + try { + IField[] fields = classType.getFields(); + for (int i = 0; i < fields.length; i++) { + char[] potential = fields[i].getNameCharArray(); + if (CharArrayUtils.equals(potential, 0, name.length, name, false)) { + bindings.add(fields[i]); + } + } + } catch (DOMException e) { + } + + try { + ICPPMethod[] methods = classType.getMethods(); + for (int i = 0; i < methods.length; i++) { + if (!(methods[i] instanceof ICPPConstructor) && !methods[i].isImplicit()) { + char[] potential = methods[i].getNameCharArray(); + if (CharArrayUtils.equals(potential, 0, name.length, name, false)) { + bindings.add(methods[i]); + } + } + } + } catch (DOMException e) { + } + + collectBases(classType, bindings, n.toCharArray()); + return (IBinding[]) bindings.toArray(new IBinding[bindings.size()]); + } + + return null; + } + private void collectBases(ICPPClassType classType, List bindings, char[] prefix) { + if (CharArrayUtils.equals(classType.getNameCharArray(), + 0, prefix.length, prefix, false)) { + bindings.add(classType); + } + + try { + ICPPBase[] bases = classType.getBases(); + for (int i = 0; i < bases.length; i++) { + IBinding base = bases[i].getBaseClass(); + if (base instanceof ICPPClassType) { + ICPPClassType baseClass = (ICPPClassType) base; + collectBases(baseClass, bindings, prefix); + } + } + } catch (DOMException e) { + } + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java index 0cb939a8191..d1ad9278ae1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java @@ -7,18 +7,28 @@ * * Contributors: * IBM - Initial API and implementation + * Bryan Wilkinson (QNX) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.index.IIndex; +import org.eclipse.cdt.core.index.IndexFilter; +import org.eclipse.cdt.core.parser.util.ArrayUtil; +import org.eclipse.cdt.internal.core.dom.Linkage; +import org.eclipse.cdt.internal.core.dom.parser.IASTCompletionContext; +import org.eclipse.core.runtime.CoreException; /** * @author jcamelon */ -public class CPPASTIdExpression extends CPPASTNode implements IASTIdExpression { +public class CPPASTIdExpression extends CPPASTNode implements IASTIdExpression, IASTCompletionContext { private IASTName name; public IASTName getName() { @@ -59,4 +69,33 @@ public class CPPASTIdExpression extends CPPASTNode implements IASTIdExpression { return CPPVisitor.getExpressionType(this); } + public IBinding[] resolvePrefix(IASTName n) { + IScope scope = CPPVisitor.getContainingScope(n); + + IBinding[] b1 = null; + if (scope != null) { + try { + b1 = scope.find(n.toString(), true); + } catch (DOMException e) { + } + } + + IIndex index = getTranslationUnit().getIndex(); + + IBinding[] b2 = null; + if (index != null) { + try { + b2 = index.findBindingsForPrefix( + n.toString(), + IndexFilter.getFilter(Linkage.CPP_LINKAGE)); + } catch (CoreException e) { + } + } + + int size = (b1 == null ? 0 : b1.length) + (b2 == null ? 0 : b2.length); + IBinding[] all = new IBinding[size]; + if (b1 != null) ArrayUtil.addAll(IBinding.class, all, b1); + if (b2 != null) ArrayUtil.addAll(IBinding.class, all, b2); + return all; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java index d3ff1750f1b..7014afa6767 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java @@ -8,6 +8,7 @@ * Contributors: * IBM - Initial API and implementation * Markus Schorn (Wind River Systems) + * Bryan Wilkinson (QNX) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -18,6 +19,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.parser.util.CharArrayUtils; +import org.eclipse.cdt.internal.core.dom.parser.IASTCompletionContext; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; /** @@ -75,7 +77,16 @@ public class CPPASTName extends CPPASTNode implements IASTName { } public IBinding[] resolvePrefix() { - return CPPSemantics.prefixLookup(this); + IASTNode node = getParent(); + while (!(node instanceof IASTCompletionContext)) { + if (node == null) { + return null; + } + node = node.getParent(); + } + + IASTCompletionContext context = (IASTCompletionContext) node; + return context.resolvePrefix(this); } public void setBinding(IBinding binding) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNamedTypeSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNamedTypeSpecifier.java index 3f3ea34b002..76b5fd660f1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNamedTypeSpecifier.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNamedTypeSpecifier.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 20057 IBM Corporation and others. + * Copyright (c) 2004, 2007 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 @@ -7,18 +7,35 @@ * * Contributors: * IBM - Initial API and implementation + * Bryan Wilkinson (QNX) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ast.ASTVisitor; +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.IEnumeration; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; +import org.eclipse.cdt.core.index.IIndex; +import org.eclipse.cdt.core.index.IndexFilter; +import org.eclipse.cdt.internal.core.dom.parser.IASTCompletionContext; +import org.eclipse.core.runtime.CoreException; /** * @author jcamelon */ public class CPPASTNamedTypeSpecifier extends CPPASTBaseDeclSpecifier implements - ICPPASTNamedTypeSpecifier { + ICPPASTNamedTypeSpecifier, IASTCompletionContext { private boolean typename; private IASTName name; @@ -79,4 +96,58 @@ public class CPPASTNamedTypeSpecifier extends CPPASTBaseDeclSpecifier implements return r_reference; return r_unclear; } + + public IBinding[] resolvePrefix(IASTName n) { + List filtered = new ArrayList(); + + IScope scope = CPPVisitor.getContainingScope(n); + + if (scope != null) { + try { + IBinding[] bindings = scope.find(n.toString(), true); + for (int i = 0; i < bindings.length; i++) { + if (bindings[i] instanceof ICPPTemplateParameter) { + filtered.add(bindings[i]); + } + } + } catch (DOMException e) { + } + } + + IndexFilter filter = new IndexFilter() { + public boolean acceptBinding(IBinding binding) { + return binding instanceof ICPPClassType + || binding instanceof IEnumeration + || binding instanceof ICPPNamespace + || binding instanceof ITypedef; + } + public boolean acceptLinkage(ILinkage linkage) { + return linkage.getID() == ILinkage.CPP_LINKAGE_ID; + } + }; + + try { + IBinding[] bindings = getTranslationUnit().getScope().find(n.toString(), true); + for (int i = 0 ; i < bindings.length; i++) { + if (filter.acceptBinding(bindings[i])) { + filtered.add(bindings[i]); + } + } + } catch (DOMException e1) { + } + + IIndex index = getTranslationUnit().getIndex(); + + if (index != null) { + try { + IBinding[] bindings = index.findBindingsForPrefix(n.toString(), filter); + for (int i = 0; i < bindings.length; i++) { + filtered.add(bindings[i]); + } + } catch (CoreException e) { + } + } + + return (IBinding[]) filtered.toArray(new IBinding[filtered.size()]); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java index ad15e03b184..e054cf2b099 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java @@ -7,10 +7,15 @@ * * Contributors: * IBM - Initial API and implementation + * Bryan Wilkinson (QNX) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import java.util.ArrayList; +import java.util.List; + import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNameOwner; import org.eclipse.cdt.core.dom.ast.IASTNode; @@ -19,13 +24,18 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTOperatorName; 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.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.parser.util.ArrayUtil; +import org.eclipse.cdt.core.parser.util.CharArrayUtils; +import org.eclipse.cdt.internal.core.dom.parser.IASTCompletionContext; /** * @author jcamelon */ public class CPPASTQualifiedName extends CPPASTNode implements - ICPPASTQualifiedName { + ICPPASTQualifiedName, IASTCompletionContext { /** * @param duple @@ -287,4 +297,45 @@ public class CPPASTQualifiedName extends CPPASTNode implements } return false; } + + public IBinding[] resolvePrefix(IASTName n) { + IBinding binding = names[names.length - 2].resolveBinding(); + if (binding instanceof ICPPClassType) { + ICPPClassType classType = (ICPPClassType) binding; + List bindings = new ArrayList(); + char[] name = n.toCharArray(); + + try { + ICPPMethod[] methods = classType.getDeclaredMethods(); + for (int i = 0; i < methods.length; i++) { + char[] potential = methods[i].getNameCharArray(); + if (CharArrayUtils.equals(potential, 0, name.length, name, false)) { + bindings.add(methods[i]); + } + } + } catch (DOMException e) { + } + + return (IBinding[]) bindings.toArray(new IBinding[bindings.size()]); + } else if (binding instanceof ICPPNamespace) { + ICPPNamespace namespace = (ICPPNamespace) binding; + List bindings = new ArrayList(); + char[] name = n.toCharArray(); + + try { + IBinding[] members = namespace.getMemberBindings(); + for (int i = 0 ; i < members.length; i++) { + char[] potential = members[i].getNameCharArray(); + if (CharArrayUtils.equals(potential, 0, name.length, name, false)) { + bindings.add(members[i]); + } + } + } catch (DOMException e) { + } + + return (IBinding[]) bindings.toArray(new IBinding[bindings.size()]); + } + + 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 5281c5d7f34..2117015245b 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 @@ -7,18 +7,32 @@ * * Contributors: * IBM - Initial API and implementation + * Bryan Wilkinson (QNX) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; +import org.eclipse.cdt.core.index.IIndex; +import org.eclipse.cdt.core.index.IndexFilter; +import org.eclipse.cdt.core.parser.util.CharArrayUtils; +import org.eclipse.cdt.internal.core.dom.parser.IASTCompletionContext; +import org.eclipse.core.runtime.CoreException; /** * @author jcamelon */ public class CPPASTUsingDeclaration extends CPPASTNode implements - ICPPASTUsingDeclaration { + ICPPASTUsingDeclaration, IASTCompletionContext { private boolean typeName; private IASTName name; @@ -80,4 +94,45 @@ public class CPPASTUsingDeclaration extends CPPASTNode implements return r_reference; return r_unclear; } + + public IBinding[] resolvePrefix(IASTName n) { + List filtered = new ArrayList(); + IndexFilter filter = new IndexFilter() { + public boolean acceptBinding(IBinding binding) { + return binding instanceof ICPPNamespace; + } + public boolean acceptLinkage(ILinkage linkage) { + return linkage.getID() == ILinkage.CPP_LINKAGE_ID; + } + }; + + IASTDeclaration[] decls = getTranslationUnit().getDeclarations(); + char[] nChars = n.toCharArray(); + for (int i = 0; i < decls.length; i++) { + if (decls[i] instanceof ICPPASTNamespaceDefinition) { + ICPPASTNamespaceDefinition defn = (ICPPASTNamespaceDefinition) decls[i]; + IASTName name = defn.getName(); + if (CharArrayUtils.equals(name.toCharArray(), 0, nChars.length, nChars, false)) { + IBinding binding = name.resolveBinding(); + if (filter.acceptBinding(binding)) { + filtered.add(binding); + } + } + } + } + + IIndex index = getTranslationUnit().getIndex(); + + if (index != null) { + try { + IBinding[] bindings = index.findBindingsForPrefix(n.toString(), filter); + for (int i = 0; i < bindings.length; i++) { + filtered.add(bindings[i]); + } + } catch (CoreException e) { + } + } + + return (IBinding[]) filtered.toArray(new IBinding[filtered.size()]); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUsingDirective.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUsingDirective.java index 1413cfef53a..773eafe9420 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUsingDirective.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUsingDirective.java @@ -7,18 +7,32 @@ * * Contributors: * IBM - Initial API and implementation + * Bryan Wilkinson (QNX) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; +import org.eclipse.cdt.core.index.IIndex; +import org.eclipse.cdt.core.index.IndexFilter; +import org.eclipse.cdt.core.parser.util.CharArrayUtils; +import org.eclipse.cdt.internal.core.dom.parser.IASTCompletionContext; +import org.eclipse.core.runtime.CoreException; /** * @author jcamelon */ public class CPPASTUsingDirective extends CPPASTNode implements - ICPPASTUsingDirective { + ICPPASTUsingDirective, IASTCompletionContext { private IASTName name; @@ -65,4 +79,45 @@ public class CPPASTUsingDirective extends CPPASTNode implements return r_reference; return r_unclear; } + + public IBinding[] resolvePrefix(IASTName n) { + List filtered = new ArrayList(); + IndexFilter filter = new IndexFilter() { + public boolean acceptBinding(IBinding binding) { + return binding instanceof ICPPNamespace; + } + public boolean acceptLinkage(ILinkage linkage) { + return linkage.getID() == ILinkage.CPP_LINKAGE_ID; + } + }; + + IASTDeclaration[] decls = getTranslationUnit().getDeclarations(); + char[] nChars = n.toCharArray(); + for (int i = 0; i < decls.length; i++) { + if (decls[i] instanceof ICPPASTNamespaceDefinition) { + ICPPASTNamespaceDefinition defn = (ICPPASTNamespaceDefinition) decls[i]; + IASTName name = defn.getName(); + if (CharArrayUtils.equals(name.toCharArray(), 0, nChars.length, nChars, false)) { + IBinding binding = name.resolveBinding(); + if (filter.acceptBinding(binding)) { + filtered.add(binding); + } + } + } + } + + IIndex index = getTranslationUnit().getIndex(); + + if (index != null) { + try { + IBinding[] bindings = index.findBindingsForPrefix(n.toString(), filter); + for (int i = 0; i < bindings.length; i++) { + filtered.add(bindings[i]); + } + } catch (CoreException e) { + } + } + + return (IBinding[]) filtered.toArray(new IBinding[filtered.size()]); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstanceScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstanceScope.java index 7f1da590c53..f0d7899b063 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstanceScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstanceScope.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2006 IBM Corporation and others. + * Copyright (c) 2005, 2007 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 @@ -8,6 +8,7 @@ * Contributors: * IBM - Initial API and implementation * Markus Schorn (Wind River Systems) + * Bryan Wilkinson (QNX) *******************************************************************************/ /* * Created on Mar 28, 2005 @@ -243,6 +244,13 @@ public class CPPClassInstanceScope implements ICPPClassScope, IASTInternalScope * @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String) */ public IBinding[] find(String name) { + return find(name, false); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String) + */ + public IBinding[] find(String name, boolean prefixLookup) { if( name != null ) {} return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java index 9f3b9a978c4..a054eee5e9b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2006 IBM Corporation and others. + * Copyright (c) 2004, 2007 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 @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Markus Schorn (Wind River Systems) + * Bryan Wilkinson (QNX) *******************************************************************************/ /* * Created on Nov 29, 2004 @@ -300,6 +301,13 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { * @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String) */ public IBinding[] find(String name) throws DOMException { + return find(name, false); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String) + */ + public IBinding[] find(String name, boolean prefixLookup) throws DOMException { char [] n = name.toCharArray(); ICPPASTCompositeTypeSpecifier compType = (ICPPASTCompositeTypeSpecifier) getPhysicalNode(); IASTName compName = compType.getName(); @@ -307,10 +315,11 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { IASTName [] ns = ((ICPPASTQualifiedName)compName).getNames(); compName = ns[ ns.length - 1 ]; } - if( CharArrayUtils.equals( n, compName.toCharArray() ) ){ + if((prefixLookup && CharArrayUtils.equals(compName.toCharArray(), 0, n.length, n, false)) + || (!prefixLookup && CharArrayUtils.equals(compName.toCharArray(), n))) { return (IBinding[]) ArrayUtil.addAll( IBinding.class, null, getConstructors( bindings, true ) ); } - return super.find( name ); + return super.find( name, prefixLookup ); } public static boolean isConstructorReference( IASTName name ){ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java index ef779629b84..2a974bf5ff0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java @@ -7,6 +7,7 @@ * * Contributors: * IBM - Initial API and implementation + * Bryan Wilkinson (QNX) *******************************************************************************/ /* * Created on Mar 31, 2005 @@ -236,7 +237,7 @@ public class CPPClassTemplate extends CPPTemplateDefinition implements * @see org.eclipse.cdt.core.dom.ast.ICompositeType#findField(java.lang.String) */ public IField findField(String name) throws DOMException { - IBinding [] bindings = CPPSemantics.findBindings( getCompositeScope(), name, true ); + IBinding [] bindings = CPPSemantics.findBindings( getCompositeScope(), name, true, false ); IField field = null; for ( int i = 0; i < bindings.length; i++ ) { if( bindings[i] instanceof IField ){ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java index 88039eb325f..56d26063c61 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2006 IBM Corporation and others. + * Copyright (c) 2004, 2007 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 @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Markus Schorn (Wind River Systems) + * Bryan Wilkinson (QNX) *******************************************************************************/ /* * Created on Nov 29, 2004 @@ -333,7 +334,7 @@ public class CPPClassType extends PlatformObject implements ICPPClassType, ICPPI * @see org.eclipse.cdt.core.dom.ast.ICompositeType#findField(java.lang.String) */ public IField findField(String name) throws DOMException { - IBinding [] bindings = CPPSemantics.findBindings( getCompositeScope(), name, true ); + IBinding [] bindings = CPPSemantics.findBindings( getCompositeScope(), name, true, false ); IField field = null; for ( int i = 0; i < bindings.length; i++ ) { if( bindings[i] instanceof IField ){ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionScope.java index 4e393bae69e..ded642c9b83 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionScope.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2006 IBM Corporation and others. + * Copyright (c) 2004, 2007 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 @@ -8,12 +8,16 @@ * Contributors: * IBM Corporation - initial API and implementation * Markus Schorn (Wind River Systems) + * Bryan Wilkinson (QNX) *******************************************************************************/ /* * Created on Dec 1, 2004 */ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import java.util.ArrayList; +import java.util.List; + import org.eclipse.cdt.core.dom.IName; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; @@ -31,6 +35,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; +import org.eclipse.cdt.core.parser.util.CharArrayUtils; /** * @author aniefer @@ -72,11 +77,30 @@ public class CPPFunctionScope extends CPPScope implements ICPPFunctionScope { * @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String) */ public IBinding[] find(String name) throws DOMException { + return find(name, false); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String) + */ + public IBinding[] find(String name, boolean prefixLookup) throws DOMException { char [] n = name.toCharArray(); - if( labels.containsKey( n ) ) - return new IBinding[] { (IBinding) labels.get( n ) }; - - return super.find( name ); + List bindings = new ArrayList(); + + for (int i = 0; i < labels.size(); i++) { + char[] key = labels.keyAt(i); + if ((prefixLookup && CharArrayUtils.equals(key, 0, n.length, n, false)) + || (!prefixLookup && CharArrayUtils.equals(key, n))) { + bindings.add(labels.get(key)); + } + } + + IBinding[] additional = super.find( name, prefixLookup ); + for (int i = 0; i < additional.length; i++) { + bindings.add(additional[i]); + } + + return (IBinding[]) bindings.toArray(new IBinding[bindings.size()]); } public IScope getParent() throws DOMException { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java index 6fe5470de34..56faf4d2ee3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2006 IBM Corporation and others. + * Copyright (c) 2004, 2007 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 @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Markus Schorn (Wind River Systems) + * Bryan Wilkinson (QNX) *******************************************************************************/ /* * Created on Nov 29, 2004 @@ -201,7 +202,14 @@ abstract public class CPPScope implements ICPPScope, IASTInternalScope { * @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String) */ public IBinding[] find(String name) throws DOMException { - return CPPSemantics.findBindings( this, name, false ); + return CPPSemantics.findBindings( this, name, false, false ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String) + */ + public IBinding[] find(String name, boolean prefixLookup) throws DOMException { + return CPPSemantics.findBindings( this, name, false, prefixLookup ); } public void flushCache() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java index d5074a949e6..6976955a3a6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2006 IBM Corporation and others. + * Copyright (c) 2004, 2007 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 @@ -8,6 +8,7 @@ * Contributors: * IBM - Initial API and implementation * Markus Schorn (Wind River Systems) + * Bryan Wilkinson (QNX) *******************************************************************************/ /* * Created on Dec 8, 2004 @@ -90,6 +91,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; +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; @@ -116,6 +118,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; +import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; @@ -127,6 +130,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; +import org.eclipse.core.runtime.CoreException; /** * @author aniefer @@ -1023,6 +1027,26 @@ public class CPPSemantics { b= scope.getBinding( data.astName, false ); if (b instanceof CPPImplicitFunction || b instanceof CPPImplicitTypedef) mergeResults( data, b, true ); + } else if (data.prefixLookup && data.astName != null) { + IASTNode parent = ASTInternal.getPhysicalNodeOfScope(scope); + if (parent == null && scope instanceof IIndexBinding) { + IBinding[] bindings = scope.find(data.astName.toString(), data.prefixLookup); + mergeResults(data, bindings, true); + } else if (scope instanceof ICPPNamespaceScope && !(scope instanceof ICPPBlockScope)) { + ICPPNamespaceScope ns = (ICPPNamespaceScope) scope; + IIndex index = parent.getTranslationUnit().getIndex(); + if (index != null) { + try { + IIndexBinding binding = index.findBinding(ns.getScopeName()); + if (binding instanceof ICPPNamespaceScope) { + ICPPNamespaceScope indexNs = (ICPPNamespaceScope) binding; + IBinding[] bindings = indexNs.find(data.astName.toString(), data.prefixLookup); + mergeResults(data, bindings, true); + } + } catch (CoreException e) { + } + } + } } IASTName[] inScope = lookupInScope( data, scope, blockItem ); if (inScope != null) { @@ -1789,8 +1813,8 @@ public class CPPSemantics { } char[] c = potential.toCharArray(); char [] n = data.name(); - return ( (data.prefixLookup && CharArrayUtils.equals( c, 0, n.length, n )) || - (!data.prefixLookup && CharArrayUtils.equals( c, n )) ); + return (data.prefixLookup && CharArrayUtils.equals(c, 0, n.length, n, false)) + || (!data.prefixLookup && CharArrayUtils.equals(c, n)); } private static void addDefinition( IBinding binding, IASTName name ){ @@ -3251,15 +3275,19 @@ public class CPPSemantics { return null; } - public static IBinding[] findBindings( IScope scope, String name, boolean qualified ) throws DOMException{ - return findBindings( scope, name.toCharArray(), qualified ); + public static IBinding[] findBindings( IScope scope, String name, boolean qualified, boolean prefixLookup ) throws DOMException{ + return findBindings( scope, name.toCharArray(), qualified, prefixLookup ); } - public static IBinding[] findBindings( IScope scope, char []name, boolean qualified ) throws DOMException{ + public static IBinding[] findBindings( IScope scope, char []name, boolean qualified, boolean prefixLookup ) throws DOMException{ CPPASTName astName = new CPPASTName(); astName.setName( name ); astName.setParent( ASTInternal.getPhysicalNodeOfScope(scope)); astName.setPropertyInParent( STRING_LOOKUP_PROPERTY ); + if (prefixLookup) { + return prefixLookup(astName, scope); + } + LookupData data = new LookupData( astName ); data.forceQualified = qualified; @@ -3296,13 +3324,17 @@ public class CPPSemantics { return (IBinding[]) set.keyArray( IBinding.class ); } - public static IBinding [] prefixLookup( IASTName name ){ + public static IBinding [] prefixLookup( IASTName name ){ + return prefixLookup(name, name); + } + + public static IBinding [] prefixLookup( IASTName name, Object start ){ LookupData data = createLookupData( name, true ); data.prefixLookup = true; data.foundItems = new CharArrayObjectMap( 2 ); try { - lookup( data, name ); + lookup( data, start ); } catch ( DOMException e ) { } CharArrayObjectMap map = (CharArrayObjectMap) data.foundItems; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownScope.java index 5160517562b..68b0383a7a3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownScope.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2006 IBM Corporation and others. + * Copyright (c) 2004, 2007 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 @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Markus Schorn (Wind River Systems) + * Bryan Wilkinson (QNX) *******************************************************************************/ /* @@ -59,7 +60,13 @@ public class CPPUnknownScope implements ICPPScope, IASTInternalScope { * @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String) */ public IBinding[] find( String name ) { - // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String) + */ + public IBinding[] find( String name, boolean prefixLookup ) { return null; } 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 91cea0979f1..1bb0e938cfe 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 2007 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 @@ -7,6 +7,7 @@ * * Contributors: * Markus Schorn - initial API and implementation + * Bryan Wilkinson (QNX) *******************************************************************************/ package org.eclipse.cdt.internal.core.index; @@ -154,8 +155,7 @@ public class CIndex implements IIndex { monitor.done(); return (IIndexBinding[]) result.toArray(new IIndexBinding[result.size()]); } - - + public IIndexName[] findNames(IBinding binding, int flags) throws CoreException { ArrayList result= new ArrayList(); for (int i = 0; i < fPrimaryFragmentCount; i++) { @@ -368,4 +368,25 @@ public class CIndex implements IIndex { } return IIndexBinding.EMPTY_INDEX_BINDING_ARRAY; } + + public IBinding[] findBindingsForPrefix(String prefix, IndexFilter filter) throws CoreException { + ArrayList result= new ArrayList(); + for (int i = 0; i < fFragments.length; i++) { + try { + IBinding[] part = fFragments[i].findBindingsForPrefix(prefix, filter); + for (int j = 0; j < part.length; j++) { + IBinding binding = part[j]; + if (binding instanceof IIndexBinding) { + result.add(binding); + } + } + } catch (CoreException e) { + CCorePlugin.log(e); + } + } + if (!result.isEmpty()) { + return (IIndexBinding[]) result.toArray(new IIndexBinding[result.size()]); + } + return IIndexBinding.EMPTY_INDEX_BINDING_ARRAY; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java index 2c388905361..685c2dcb791 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/EmptyCIndex.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 2007 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 @@ -7,6 +7,7 @@ * * Contributors: * Markus Schorn - initial API and implementation + * Bryan Wilkinson (QNX) *******************************************************************************/ package org.eclipse.cdt.internal.core.index; @@ -93,7 +94,7 @@ final public class EmptyCIndex implements IIndex { public IIndexBinding[] findBindings(Pattern[] pattern, boolean isFullyQualified, IndexFilter filter, IProgressMonitor monitor) throws CoreException { return IIndexFragmentBinding.EMPTY_INDEX_BINDING_ARRAY; } - + public IIndexBinding adaptBinding(IBinding binding) throws CoreException { return null; } @@ -105,4 +106,8 @@ final public class EmptyCIndex implements IIndex { public IBinding[] findInNamespace(IBinding nsbinding, char[] name) { return IIndexBinding.EMPTY_INDEX_BINDING_ARRAY; } + + public IBinding[] findBindingsForPrefix(String prefix, IndexFilter filter) throws CoreException { + return IIndexBinding.EMPTY_INDEX_BINDING_ARRAY; + } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java index 8bdd97f3d2a..fedb7fed1ed 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 2007 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 @@ -7,6 +7,7 @@ * * Contributors: * Markus Schorn - initial API and implementation + * Bryan Wilkinson (QNX) *******************************************************************************/ package org.eclipse.cdt.internal.core.index; @@ -143,4 +144,9 @@ public interface IIndexFragment { * Returns all bindings with the given name in the given namespace */ IBinding[] findInNamespace(IBinding nsbinding, char[] name) throws CoreException; + + /** + * Returns all bindings with the given prefix, accepted by the given filter + */ + IBinding[] findBindingsForPrefix(String prefix, IndexFilter filter) throws CoreException; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java index c1670910c13..14b96f30373 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java @@ -95,6 +95,7 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM { // 20 - add pointer to member types, array types, return types for functions // 21 - change representation of paths in the pdom (167549) // 22 - fix inheritance relations (167396) + // 23 - types on c-variables, return types on c-functions public static final int LINKAGES = Database.DATA_AREA; public static final int FILE_INDEX = Database.DATA_AREA + 4; @@ -257,13 +258,13 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM { private List bindings = new ArrayList(); private boolean isFullyQualified; private BitSet matchesUpToLevel; - private boolean acceptImplicitMethods; + private IndexFilter filter; - public BindingFinder(Pattern[] pattern, boolean isFullyQualified, boolean acceptImplicitMethods, IProgressMonitor monitor) { + public BindingFinder(Pattern[] pattern, boolean isFullyQualified, IndexFilter filter, IProgressMonitor monitor) { this.pattern = pattern; this.monitor = monitor; this.isFullyQualified= isFullyQualified; - this.acceptImplicitMethods= acceptImplicitMethods; + this.filter= filter; matchesUpToLevel= new BitSet(); matchesUpToLevel.set(0); matchStack.add(matchesUpToLevel); @@ -280,9 +281,11 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM { // check if we have a complete match. final int lastIdx = pattern.length-1; if (matchesUpToLevel.get(lastIdx) && pattern[lastIdx].matcher(name).matches()) { - if (acceptImplicitMethods || !(binding instanceof ICPPMethod) || + if (filter.acceptImplicitMethods() || !(binding instanceof ICPPMethod) || !((ICPPMethod)binding).isImplicit()) { - bindings.add(binding); + if (filter.acceptBinding(binding)) { + bindings.add(binding); + } } } @@ -344,7 +347,7 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM { } public IIndexFragmentBinding[] findBindings(Pattern[] pattern, boolean isFullyQualified, IndexFilter filter, IProgressMonitor monitor) throws CoreException { - BindingFinder finder = new BindingFinder(pattern, isFullyQualified, filter.acceptImplicitMethods(), monitor); + BindingFinder finder = new BindingFinder(pattern, isFullyQualified, filter, monitor); for (Iterator iter = fLinkageIDCache.values().iterator(); iter.hasNext();) { PDOMLinkage linkage = (PDOMLinkage) iter.next(); if (filter.acceptLinkage(linkage)) { @@ -614,4 +617,18 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM { } return IIndexBinding.EMPTY_INDEX_BINDING_ARRAY; } + + public IBinding[] findBindingsForPrefix(String prefix, IndexFilter filter) throws CoreException { + ArrayList result = new ArrayList(); + for (Iterator iter = fLinkageIDCache.values().iterator(); iter.hasNext();) { + PDOMLinkage linkage = (PDOMLinkage) iter.next(); + if (filter.acceptLinkage(linkage)) { + IBinding[] bindings = linkage.findBindingsForPrefix(prefix, filter); + for (int j = 0; j < bindings.length; j++) { + result.add(bindings[j]); + } + } + } + return (IBinding[]) result.toArray(new IBinding[result.size()]); + } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/FindBindingsInBTree.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/FindBindingsInBTree.java index ce7bce64539..4f6b47934fe 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/FindBindingsInBTree.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/FindBindingsInBTree.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006 QNX Software Systems and others. + * Copyright (c) 2006, 2007 QNX Software Systems 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 @@ -14,17 +14,24 @@ import java.util.ArrayList; import java.util.List; import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor; +import org.eclipse.cdt.internal.core.pdom.db.IString; import org.eclipse.core.runtime.CoreException; public final class FindBindingsInBTree implements IBTreeVisitor { protected final PDOMLinkage linkage; protected final char[] name; + protected final boolean prefixLookup; public int compare(int record) throws CoreException { - PDOMNamedNode node = ((PDOMNamedNode)linkage.getNode(record)); - return node.getDBName().compare(name); + PDOMNamedNode node = ((PDOMNamedNode)linkage.getNode(record)); + IString n = node.getDBName(); + if (prefixLookup && n.getString().startsWith(new String(name))) { + return 0; + } + return n.compare(name); } private List bindings = new ArrayList(); @@ -59,9 +66,22 @@ public final class FindBindingsInBTree implements IBTreeVisitor { * @param desiredType */ public FindBindingsInBTree(PDOMLinkage linkage, char[] name, int[] desiredType) { + this(linkage, name, desiredType, false); + } + + /** + * Match a collection of types. + * + * @param pdom + * @param name + * @param desiredType + * @param prefixLookup + */ + public FindBindingsInBTree(PDOMLinkage linkage, char[] name, int[] desiredType, boolean prefixLookup) { this.name = name; this.desiredType = desiredType; this.linkage= linkage; + this.prefixLookup = prefixLookup; } public boolean visit(int record) throws CoreException { @@ -69,8 +89,10 @@ public final class FindBindingsInBTree implements IBTreeVisitor { return true; PDOMBinding tBinding = linkage.getPDOM().getBinding(record); - if (!tBinding.hasName(name)) - // no more bindings with our desired name + if ((!prefixLookup && !tBinding.hasName(name)) + || (prefixLookup && !CharArrayUtils.equals( + tBinding.getNameCharArray(), + 0, name.length, name, false))) return false; if (desiredType == null) { 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 4df9d48f900..448c4561e4e 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 @@ -14,6 +14,9 @@ package org.eclipse.cdt.internal.core.pdom.dom; +import java.util.ArrayList; +import java.util.List; + import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.IName; import org.eclipse.cdt.core.dom.IPDOMVisitor; @@ -29,9 +32,11 @@ import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexLinkage; +import org.eclipse.cdt.core.index.IndexFilter; import org.eclipse.cdt.internal.core.Util; import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; import org.eclipse.cdt.internal.core.pdom.PDOM; @@ -228,6 +233,50 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage return visitor.getBinding(); } + private static class PrefixedBindingFinder implements IBTreeVisitor { + private PDOMLinkage linkage; + private String prefix; + private IndexFilter filter; + private List bindings = new ArrayList(); + + PrefixedBindingFinder(PDOMLinkage linkage, String prefix, IndexFilter filter) { + this.linkage = linkage; + this.prefix = prefix; + this.filter = filter; + } + + public int compare(int record) throws CoreException { + PDOMNamedNode node = (PDOMNamedNode) linkage.getNode(record); + IString name = node.getDBName(); + if (name.getString().startsWith(prefix)) { + return 0; + } + return name.compare(prefix); + } + + public boolean visit(int record) throws CoreException { + PDOMBinding binding = linkage.getPDOM().getBinding(record); + if (filter.acceptImplicitMethods() || !(binding instanceof ICPPMethod) || + !((ICPPMethod)binding).isImplicit()) { + if (filter.acceptBinding(binding)) { + bindings.add(binding); + } + } + return true; + } + + public IBinding[] getBindings() { + return (IBinding[]) bindings.toArray(new IBinding[bindings.size()]); + } + } + + public IBinding[] findBindingsForPrefix(String prefix, IndexFilter filter) throws CoreException { + PrefixedBindingFinder visitor = new PrefixedBindingFinder(this, prefix, filter); + getIndex().accept(visitor); + + return visitor.getBindings(); + } + /** * Callback informing the linkage that a name has been added. This is * used to do addtional processing, like establishing inheritance relationships. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCField.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCField.java index 5960cc68b18..a1d20c3af72 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCField.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCField.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006 QNX Software Systems and others. + * Copyright (c) 2006, 2007 QNX Software Systems 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 @@ -14,10 +14,8 @@ package org.eclipse.cdt.internal.core.pdom.dom.c; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IField; -import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.dom.IPDOMMemberOwner; -import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.core.runtime.CoreException; @@ -25,10 +23,10 @@ import org.eclipse.core.runtime.CoreException; * @author Doug Schaefer * */ -class PDOMCField extends PDOMBinding implements IField { +class PDOMCField extends PDOMCVariable implements IField { public PDOMCField(PDOM pdom, IPDOMMemberOwner parent, IField field) throws CoreException { - super(pdom, (PDOMNode) parent, field.getNameCharArray()); + super(pdom, (PDOMNode) parent, field); } public PDOMCField(PDOM pdom, int record) { @@ -42,12 +40,6 @@ class PDOMCField extends PDOMBinding implements IField { public int getNodeType() { return PDOMCLinkage.CFIELD; } - - public IType getType() throws DOMException { - return null; - // TODO - do we need the real type? - //throw new PDOMNotImplementedError(); - } public boolean isStatic() throws DOMException { // ISO/IEC 9899:TC1 6.7.2.1 diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCFunction.java index 67d31da4a93..ccda8d73760 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCFunction.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006 QNX Software Systems and others. + * Copyright (c) 2006, 2007 QNX Software Systems 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 @@ -43,21 +43,36 @@ class PDOMCFunction extends PDOMBinding implements IFunction { */ public static final int FIRST_PARAM = PDOMBinding.RECORD_SIZE + 4; + /** + * Offset for return type of this function (relative to + * the beginning of the record). + */ + private static final int RETURN_TYPE = PDOMBinding.RECORD_SIZE + 8; + /** * Offset of annotation information (relative to the beginning of the * record). */ - private static final int ANNOTATIONS = PDOMBinding.RECORD_SIZE + 8; // byte + private static final int ANNOTATIONS = PDOMBinding.RECORD_SIZE + 12; // byte /** * The size in bytes of a PDOMCPPFunction record in the database. */ - public static final int RECORD_SIZE = PDOMBinding.RECORD_SIZE + 9; + public static final int RECORD_SIZE = PDOMBinding.RECORD_SIZE + 13; public PDOMCFunction(PDOM pdom, PDOMNode parent, IFunction function) throws CoreException { super(pdom, parent, function.getNameCharArray()); try { + IFunctionType ft= function.getType(); + IType rt= ft.getReturnType(); + if (rt != null) { + PDOMNode typeNode = getLinkageImpl().addType(this, rt); + if (typeNode != null) { + pdom.getDB().putInt(record + RETURN_TYPE, typeNode.getRecord()); + } + } + IParameter[] params = function.getParameters(); pdom.getDB().putInt(record + NUM_PARAMS, params.length); for (int i = 0; i < params.length; ++i) { @@ -173,8 +188,19 @@ class PDOMCFunction extends PDOMBinding implements IFunction { return getBit(getByte(record + ANNOTATIONS), PDOMCAnnotation.VARARGS_OFFSET); } + public IType getReturnType() throws DOMException { + try { + PDOMNode node = getLinkageImpl().getNode(pdom.getDB().getInt(record + RETURN_TYPE)); + if (node instanceof IType) { + return (IType) node; + } + } catch (CoreException e) { + CCorePlugin.log(e); + } + return null; + } + public IScope getFunctionScope() throws DOMException {fail(); return null;} - public IType getReturnType() throws DOMException {fail();return null;} public boolean isSameType(IType type) {fail(); return false;} public Object clone() {fail(); return null;} } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCStructure.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCStructure.java index 6c008da4ccd..6794f7333c5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCStructure.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCStructure.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006 QNX Software Systems and others. + * Copyright (c) 2006, 2007 QNX Software Systems 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 @@ -28,12 +28,14 @@ import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.c.ICCompositeTypeScope; +import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.Util; import org.eclipse.cdt.internal.core.index.IIndexType; import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.db.PDOMNodeLinkedList; import org.eclipse.cdt.internal.core.pdom.dom.IPDOMMemberOwner; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNamedNode; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError; import org.eclipse.core.runtime.CoreException; @@ -196,11 +198,49 @@ public class PDOMCStructure extends PDOMBinding implements ICompositeType, ICCom fail(); return null; } - public IBinding[] find(String name) throws DOMException { - fail(); return null; - } - public IBinding getBinding(IASTName name, boolean resolve) throws DOMException { fail(); return null; } + + private static class BindingFinder implements IPDOMVisitor { + private List fBindings = new ArrayList(); + private char[] fName; + private boolean fPrefixLookup; + + public BindingFinder(char[] name, boolean prefiexLookup) { + fName= name; + fPrefixLookup= prefiexLookup; + } + + public boolean visit(IPDOMNode node) throws CoreException { + if (node instanceof PDOMNamedNode && node instanceof IBinding) { + char[] n= ((PDOMNamedNode) node).getDBName().getChars(); + if ((fPrefixLookup && CharArrayUtils.equals(n, 0, fName.length, fName, false)) + || (!fPrefixLookup && CharArrayUtils.equals(n, fName))) { + fBindings.add(node); + } + } + return false; + } + public void leave(IPDOMNode node) throws CoreException { + } + public IBinding[] getBindings() { + return (IBinding[])fBindings.toArray(new IBinding[fBindings.size()]); + } + } + + public IBinding[] find(String name) throws DOMException { + return find(name, false); + } + + public IBinding[] find(String name, boolean prefixLookup) throws DOMException { + try { + BindingFinder visitor= new BindingFinder(name.toCharArray(), prefixLookup); + accept(visitor); + return visitor.getBindings(); + } catch (CoreException e) { + CCorePlugin.log(e); + } + return null; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCVariable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCVariable.java index 0bc53065257..d0369607abc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCVariable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCVariable.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006 QNX Software Systems and others. + * Copyright (c) 2006, 2007 QNX Software Systems 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 @@ -12,11 +12,13 @@ package org.eclipse.cdt.internal.core.pdom.dom.c; +import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.internal.core.Util; import org.eclipse.cdt.internal.core.pdom.PDOM; +import org.eclipse.cdt.internal.core.pdom.db.Database; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.core.runtime.CoreException; @@ -27,21 +29,33 @@ import org.eclipse.core.runtime.CoreException; */ class PDOMCVariable extends PDOMBinding implements IVariable { + /** + * Offset of pointer to type information for this parameter + * (relative to the beginning of the record). + */ + private static final int TYPE_OFFSET = PDOMBinding.RECORD_SIZE + 0; + /** * Offset of annotation information (relative to the beginning of the * record). */ - private static final int ANNOTATIONS = PDOMBinding.RECORD_SIZE + 0; + private static final int ANNOTATIONS = PDOMBinding.RECORD_SIZE + 4; /** * The size in bytes of a PDOMCVariable record in the database. */ - protected static final int RECORD_SIZE = PDOMBinding.RECORD_SIZE + 1; + protected static final int RECORD_SIZE = PDOMBinding.RECORD_SIZE + 5; public PDOMCVariable(PDOM pdom, PDOMNode parent, IVariable variable) throws CoreException { super(pdom, parent, variable.getNameCharArray()); try { + // Find the type record + Database db = pdom.getDB(); + PDOMNode typeNode = parent.getLinkageImpl().addType(this, variable.getType()); + if (typeNode != null) + db.putInt(record + TYPE_OFFSET, typeNode.getRecord()); + pdom.getDB().putByte(record + ANNOTATIONS, PDOMCAnnotation.encodeAnnotation(variable)); } catch (DOMException e) { throw new CoreException(Util.createStatus(e)); @@ -61,9 +75,13 @@ class PDOMCVariable extends PDOMBinding implements IVariable { } public IType getType() throws DOMException { - return null; - // TODO - do we need the real type? - //throw new PDOMNotImplementedError(); + try { + int typeRec = pdom.getDB().getInt(record + TYPE_OFFSET); + return (IType)getLinkageImpl().getNode(typeRec); + } catch (CoreException e) { + CCorePlugin.log(e); + return null; + } } public boolean isStatic() throws DOMException { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPBase.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPBase.java index b3aab63bd42..6c1cdef0802 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPBase.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPBase.java @@ -16,6 +16,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.db.Database; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; import org.eclipse.cdt.internal.core.pdom.dom.PDOMName; import org.eclipse.core.runtime.CoreException; @@ -83,8 +84,13 @@ class PDOMCPPBase implements ICPPBase { public IBinding getBaseClass() { try { PDOMName name= getBaseClassSpecifierImpl(); - if (name != null) - return name.getPDOMBinding(); + if (name != null) { + PDOMBinding b = name.getPDOMBinding(); + while( b instanceof PDOMCPPTypedef && ((PDOMCPPTypedef)b).getType() instanceof PDOMBinding ){ + b = (PDOMBinding) ((PDOMCPPTypedef)b).getType(); + } + return b; + } } catch (CoreException e) { CCorePlugin.log(e); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java index 96953c06ced..7b24640c489 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java @@ -35,6 +35,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; +import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.Util; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassScope; @@ -169,6 +170,7 @@ ICPPClassScope, IPDOMMemberOwner, IIndexType { acceptInHierarchy(new HashSet(), methods); return methods.getMethods(); } catch (CoreException e) { + CCorePlugin.log(e); return new ICPPMethod[0]; } } @@ -401,12 +403,54 @@ ICPPClassScope, IPDOMMemberOwner, IIndexType { return null; } + private static class BindingFinder implements IPDOMVisitor { + private List fBindings = new ArrayList(); + private char[] fName; + private boolean fPrefixLookup; + + public BindingFinder(char[] name, boolean prefiexLookup) { + fName= name; + fPrefixLookup= prefiexLookup; + } + + public boolean visit(IPDOMNode node) throws CoreException { + if (node instanceof PDOMNamedNode && node instanceof IBinding + && !(node instanceof ICPPConstructor)) { + char[] n= ((PDOMNamedNode) node).getDBName().getChars(); + if ((fPrefixLookup && CharArrayUtils.equals(n, 0, fName.length, fName, false)) + || (!fPrefixLookup && CharArrayUtils.equals(n, fName))) { + fBindings.add(node); + } + } + return false; + } + public void leave(IPDOMNode node) throws CoreException { + } + public IBinding[] getBindings() { + return (IBinding[])fBindings.toArray(new IBinding[fBindings.size()]); + } + } + + public IBinding[] find(String name) throws DOMException { + return find(name, false); + } + + public IBinding[] find(String name, boolean prefixLookup) throws DOMException { + try { + BindingFinder visitor= new BindingFinder(name.toCharArray(), prefixLookup); + acceptInHierarchy(new HashSet(), visitor); + return visitor.getBindings(); + } catch (CoreException e) { + CCorePlugin.log(e); + } + return null; + } + // Not implemented public Object clone() {fail();return null;} public IField findField(String name) throws DOMException {fail();return null;} public IBinding[] getFriends() throws DOMException {fail();return null;} - public IBinding[] find(String name) throws DOMException {fail();return null;} public IScope getParent() throws DOMException { try { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPNamespace.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPNamespace.java index e80995ba984..5f29b8651c3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPNamespace.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPNamespace.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006 QNX Software Systems and others. + * Copyright (c) 2006, 2007 QNX Software Systems 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 @@ -9,6 +9,7 @@ * QNX - Initial API and implementation * Markus Schorn (Wind River Systems) * Andrew Ferguson (Symbian) + * Bryan Wilkinson (QNX) *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom.cpp; @@ -16,7 +17,11 @@ package org.eclipse.cdt.internal.core.pdom.dom.cpp; import java.util.ArrayList; import java.util.List; +import java.util.ArrayList; +import java.util.List; + import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.IPDOMNode; import org.eclipse.cdt.core.dom.IPDOMVisitor; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTName; @@ -31,6 +36,7 @@ import org.eclipse.cdt.internal.core.pdom.db.BTree; import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor; import org.eclipse.cdt.internal.core.pdom.dom.FindBindingsInBTree; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNamedNode; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.core.runtime.CoreException; @@ -96,8 +102,12 @@ class PDOMCPPNamespace extends PDOMCPPBinding implements ICPPNamespace, ICPPName } public IBinding[] find(String name) { + return find(name, false); + } + + public IBinding[] find(String name, boolean prefixLookup) { try { - FindBindingsInBTree visitor = new FindBindingsInBTree(getLinkageImpl(), name.toCharArray()); + FindBindingsInBTree visitor = new FindBindingsInBTree(getLinkageImpl(), name.toCharArray(), null, prefixLookup); getIndex().accept(visitor); return visitor.getBinding(); } catch (CoreException e) {