1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-09-07 10:33:26 +02:00

Fix for Bug 174840 - IASTCompletionContext finds duplicate bindings (Patch by Bryan Wilkinson)

This commit is contained in:
Anton Leherbauer 2007-02-22 11:19:01 +00:00
parent 335ae395bd
commit 71628f81e4
18 changed files with 313 additions and 595 deletions

View file

@ -2169,7 +2169,7 @@ public class AST2CPPTests extends AST2BaseTest {
tu.accept(col); tu.accept(col);
IASTName name = col.getName(11); IASTName name = col.getName(11);
IBinding[] bs = CPPSemantics.prefixLookup(name); IBinding[] bs = CPPSemantics.findBindingsForContentAssist(name, true);
assertEquals(4, bs.length); assertEquals(4, bs.length);
} }

View file

@ -12,23 +12,15 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c; 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.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTCompletionContext; import org.eclipse.cdt.core.dom.ast.IASTCompletionContext;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFieldReference; import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; 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.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.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPSemantics;
/** /**
* @author jcamelon * @author jcamelon
@ -105,37 +97,6 @@ public class CASTFieldReference extends CASTNode implements IASTFieldReference,
} }
public IBinding[] findBindings(IASTName n, boolean isPrefix) { public IBinding[] findBindings(IASTName n, boolean isPrefix) {
IASTExpression expression = getFieldOwner(); return CVisitor.findBindingsForContentAssist(n, isPrefix);
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 (nameMatches(potential, name, isPrefix)) {
bindings.add(fields[i]);
}
}
} catch (DOMException e) {
}
return (IBinding[]) bindings.toArray(new IBinding[bindings.size()]);
}
return null;
}
private boolean nameMatches(char[] potential, char[] name, boolean isPrefix) {
if (isPrefix) {
return CharArrayUtils.equals(potential, 0, name.length, name, false);
} else {
return CharArrayUtils.equals(potential, name);
}
} }
} }

View file

@ -12,20 +12,12 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c; package org.eclipse.cdt.internal.core.dom.parser.c;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTCompletionContext; import org.eclipse.cdt.core.dom.ast.IASTCompletionContext;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType; 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.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
/** /**
* @author jcamelon * @author jcamelon
@ -73,33 +65,6 @@ public class CASTIdExpression extends CASTNode implements IASTIdExpression, IAST
} }
public IBinding[] findBindings(IASTName n, boolean isPrefix) { public IBinding[] findBindings(IASTName n, boolean isPrefix) {
IScope scope = CVisitor.getContainingScope(n); return CVisitor.findBindingsForContentAssist(n, isPrefix);
IBinding[] b1 = null;
if (scope != null) {
try {
b1 = scope.find(n.toString(), isPrefix);
} catch (DOMException e) {
}
}
IIndex index = getTranslationUnit().getIndex();
IBinding[] b2 = null;
if (index != null) {
try {
IndexFilter filter = IndexFilter.getFilter(ILinkage.C_LINKAGE_ID);
b2 = isPrefix ?
index.findBindingsForPrefix(n.toCharArray(), filter) :
index.findBindings(n.toCharArray(), filter, new NullProgressMonitor());
} 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;
} }
} }

View file

@ -15,21 +15,14 @@ package org.eclipse.cdt.internal.core.dom.parser.c;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; 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.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTCompletionContext; import org.eclipse.cdt.core.dom.ast.IASTCompletionContext;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration; 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.ITypedef;
import org.eclipse.cdt.core.dom.ast.c.ICASTTypedefNameSpecifier; 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.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
/** /**
* @author jcamelon * @author jcamelon
@ -80,46 +73,15 @@ public class CASTTypedefNameSpecifier extends CASTBaseDeclSpecifier implements
} }
public IBinding[] findBindings(IASTName n, boolean isPrefix) { public IBinding[] findBindings(IASTName n, boolean isPrefix) {
IBinding[] bindings = CVisitor.findBindingsForContentAssist(n, isPrefix);
List filtered = new ArrayList(); 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(), isPrefix);
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 = isPrefix ?
index.findBindingsForPrefix(n.toCharArray(), filter) :
index.findBindings(n.toCharArray(), filter, new NullProgressMonitor());
for (int i = 0; i < bindings.length; i++) { for (int i = 0; i < bindings.length; i++) {
if (bindings[i] instanceof ICompositeType
|| bindings[i] instanceof IEnumeration
|| bindings[i] instanceof ITypedef) {
filtered.add(bindings[i]); filtered.add(bindings[i]);
} }
} catch (CoreException e) {
}
} }
return (IBinding[]) filtered.toArray(new IBinding[filtered.size()]); return (IBinding[]) filtered.toArray(new IBinding[filtered.size()]);

View file

@ -17,6 +17,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator; import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
@ -94,6 +95,7 @@ import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression;
import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.gnu.c.IGCCASTSimpleDeclSpecifier; import org.eclipse.cdt.core.dom.ast.gnu.c.IGCCASTSimpleDeclSpecifier;
import org.eclipse.cdt.core.index.IIndex; 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.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
@ -102,6 +104,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
/** /**
* Created on Nov 5, 2004 * Created on Nov 5, 2004
@ -1194,8 +1197,14 @@ public class CVisitor {
} }
} else if ( parent instanceof IASTTranslationUnit ){ } else if ( parent instanceof IASTTranslationUnit ){
IASTTranslationUnit translation = (IASTTranslationUnit) parent; IASTTranslationUnit translation = (IASTTranslationUnit) parent;
if (!prefix || translation.getIndex() == null) {
nodes = translation.getDeclarations(); nodes = translation.getDeclarations();
scope = (ICScope) translation.getScope(); scope = (ICScope) translation.getScope();
} else {
//The index will be search later
nodes = null;
scope = null;
}
} else if( parent instanceof IASTStandardFunctionDeclarator ){ } else if( parent instanceof IASTStandardFunctionDeclarator ){
IASTStandardFunctionDeclarator dtor = (IASTStandardFunctionDeclarator) parent; IASTStandardFunctionDeclarator dtor = (IASTStandardFunctionDeclarator) parent;
nodes = dtor.getParameters(); nodes = dtor.getParameters();
@ -1306,6 +1315,24 @@ public class CVisitor {
for ( int i = 0; i < vals.length; i++ ) { for ( int i = 0; i < vals.length; i++ ) {
result = (IBinding[]) ArrayUtil.append( IBinding.class, result, ((IASTName) vals[i]).resolveBinding() ); result = (IBinding[]) ArrayUtil.append( IBinding.class, result, ((IASTName) vals[i]).resolveBinding() );
} }
IASTTranslationUnit tu = (IASTTranslationUnit)blockItem;
IIndex index = tu.getIndex();
if (index != null) {
try {
IndexFilter filter = IndexFilter
.getFilter(ILinkage.C_LINKAGE_ID);
IBinding[] bindings = prefix ? index.findBindingsForPrefix(
name.toCharArray(), filter) : index.findBindings(
name.toCharArray(), filter,
new NullProgressMonitor());
result = (IBinding[]) ArrayUtil.addAll(IBinding.class, result, bindings);
} catch (CoreException e) {
CCorePlugin.log(e);
}
}
return ArrayUtil.trim( IBinding.class, result ); return ArrayUtil.trim( IBinding.class, result );
} }
if( blockItem != null) { if( blockItem != null) {
@ -1899,15 +1926,15 @@ public class CVisitor {
return null; return null;
} }
public static IBinding [] prefixLookup( IASTName name ){ public static IBinding [] findBindingsForContentAssist( IASTName name, boolean isPrefix ){
ASTNodeProperty prop = name.getPropertyInParent(); ASTNodeProperty prop = name.getPropertyInParent();
IBinding [] result = null; IBinding [] result = null;
if( prop == IASTFieldReference.FIELD_NAME ){ if( prop == IASTFieldReference.FIELD_NAME ){
result = (IBinding[]) findBinding( (IASTFieldReference) name.getParent(), true ); result = (IBinding[]) findBinding( (IASTFieldReference) name.getParent(), isPrefix );
} else { } else {
int bits = PREFIX_LOOKUP; int bits = isPrefix ? PREFIX_LOOKUP : COMPLETE;
if( prop == IASTElaboratedTypeSpecifier.TYPE_NAME ){ if( prop == IASTElaboratedTypeSpecifier.TYPE_NAME ){
bits |= TAGS; bits |= TAGS;
} else if( prop == IASTIdExpression.ID_NAME ){ } else if( prop == IASTIdExpression.ID_NAME ){
@ -1916,7 +1943,8 @@ public class CVisitor {
IASTNode blockItem = getContainingBlockItem( name ); IASTNode blockItem = getContainingBlockItem( name );
try { try {
result = (IBinding[]) findBinding( blockItem, name, bits ); result = isPrefix ? (IBinding[]) findBinding( blockItem, name, bits ) :
new IBinding[] { (IBinding) findBinding( blockItem, name, bits ) };
} catch ( DOMException e ) { } catch ( DOMException e ) {
} }
} }

View file

@ -14,20 +14,14 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; 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.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTCompletionContext; import org.eclipse.cdt.core.dom.ast.IASTCompletionContext;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor; 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.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; 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.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
/** /**
* @author jcamelon * @author jcamelon
@ -113,52 +107,31 @@ public class CPPASTBaseSpecifier extends CPPASTNode implements
} }
public IBinding[] findBindings(IASTName n, boolean isPrefix) { public IBinding[] findBindings(IASTName n, boolean isPrefix) {
IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix);
List filtered = new ArrayList(); List filtered = new ArrayList();
IndexFilter filter = new IndexFilter(){
public boolean acceptBinding(IBinding binding) { ICPPClassType classType = null;
if (getParent() instanceof CPPASTCompositeTypeSpecifier) {
IASTName className = ((CPPASTCompositeTypeSpecifier) getParent()).getName();
IBinding binding = className.resolveBinding();
if (binding instanceof ICPPClassType) { if (binding instanceof ICPPClassType) {
ICPPClassType classType = (ICPPClassType) binding; classType = (ICPPClassType) binding;
}
}
for (int i = 0; i < bindings.length; i++) {
if (bindings[i] instanceof ICPPClassType) {
ICPPClassType base = (ICPPClassType) bindings[i];
try { try {
int key = classType.getKey(); int key = base.getKey();
if (key == ICPPClassType.k_class) { if (key == ICPPClassType.k_class &&
return true; (classType == null || !base.isSameType(classType))) {
filtered.add(base);
} }
} catch (DOMException e) { } 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(), isPrefix);
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 = isPrefix ?
index.findBindingsForPrefix(n.toCharArray(), filter) :
index.findBindings(n.toCharArray(), filter, new NullProgressMonitor());
for (int i = 0; i < bindings.length; i++) {
filtered.add(bindings[i]);
}
} catch (CoreException e) {
}
} }
return (IBinding[]) filtered.toArray(new IBinding[filtered.size()]); return (IBinding[]) filtered.toArray(new IBinding[filtered.size()]);

View file

@ -15,20 +15,14 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTCompletionContext; import org.eclipse.cdt.core.dom.ast.IASTCompletionContext;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; 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.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference; 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.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.IASTAmbiguityParent;
/** /**
@ -116,73 +110,19 @@ public class CPPASTFieldReference extends CPPASTNode implements
} }
public IBinding[] findBindings(IASTName n, boolean isPrefix) { public IBinding[] findBindings(IASTName n, boolean isPrefix) {
IASTExpression expression = getFieldOwner(); IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix);
IType type = expression.getExpressionType(); List filtered = new ArrayList();
type = CPPSemantics.getUltimateType(type, true); //stop at pointer to member?
if (type instanceof ICPPClassType) { for (int i = 0; i < bindings.length; i++) {
ICPPClassType classType = (ICPPClassType) type; if (bindings[i] instanceof ICPPMethod) {
List bindings = new ArrayList(); ICPPMethod method = (ICPPMethod) bindings[i];
char[] name = n.toCharArray(); if (method.isImplicit()) {
continue;
try {
IField[] fields = classType.getFields();
if (fields != null) {
for (int i = 0; i < fields.length; i++) {
char[] potential = fields[i].getNameCharArray();
if (nameMatches(potential, name, isPrefix)) {
bindings.add(fields[i]);
} }
} }
} filtered.add(bindings[i]);
} catch (DOMException e) {
} }
try { return (IBinding[]) filtered.toArray(new IBinding[filtered.size()]);
ICPPMethod[] methods = classType.getMethods();
if (methods != null) {
for (int i = 0; i < methods.length; i++) {
if (!(methods[i] instanceof ICPPConstructor) && !methods[i].isImplicit()) {
char[] potential = methods[i].getNameCharArray();
if (nameMatches(potential, name, isPrefix)) {
bindings.add(methods[i]);
}
}
}
}
} catch (DOMException e) {
}
collectBases(classType, bindings, n.toCharArray(), isPrefix);
return (IBinding[]) bindings.toArray(new IBinding[bindings.size()]);
}
return null;
}
private void collectBases(ICPPClassType classType, List bindings, char[] name, boolean isPrefix) {
if (nameMatches(classType.getNameCharArray(), name, isPrefix)) {
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, name, isPrefix);
}
}
} catch (DOMException e) {
}
}
private boolean nameMatches(char[] potential, char[] name, boolean isPrefix) {
if (isPrefix) {
return CharArrayUtils.equals(potential, 0, name.length, name, false);
} else {
return CharArrayUtils.equals(potential, name);
}
} }
} }

View file

@ -11,20 +11,12 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTCompletionContext; import org.eclipse.cdt.core.dom.ast.IASTCompletionContext;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType; 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.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
/** /**
* @author jcamelon * @author jcamelon
@ -71,33 +63,6 @@ public class CPPASTIdExpression extends CPPASTNode implements IASTIdExpression,
} }
public IBinding[] findBindings(IASTName n, boolean isPrefix) { public IBinding[] findBindings(IASTName n, boolean isPrefix) {
IScope scope = CPPVisitor.getContainingScope(n); return CPPSemantics.findBindingsForContentAssist(n, isPrefix);
IBinding[] b1 = null;
if (scope != null) {
try {
b1 = scope.find(n.toString(), isPrefix);
} catch (DOMException e) {
}
}
IIndex index = getTranslationUnit().getIndex();
IBinding[] b2 = null;
if (index != null) {
try {
IndexFilter filter = IndexFilter.getFilter(ILinkage.CPP_LINKAGE_ID);
b2 = isPrefix ?
index.findBindingsForPrefix(n.toCharArray(), filter) :
index.findBindings(n.toCharArray(), filter, new NullProgressMonitor());
} 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;
} }
} }

View file

@ -14,23 +14,16 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; 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.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTCompletionContext; import org.eclipse.cdt.core.dom.ast.IASTCompletionContext;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IEnumeration; 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.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; 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.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
/** /**
* @author jcamelon * @author jcamelon
@ -99,57 +92,18 @@ public class CPPASTNamedTypeSpecifier extends CPPASTBaseDeclSpecifier implements
} }
public IBinding[] findBindings(IASTName n, boolean isPrefix) { public IBinding[] findBindings(IASTName n, boolean isPrefix) {
IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix);
List filtered = new ArrayList(); List filtered = new ArrayList();
IScope scope = CPPVisitor.getContainingScope(n);
if (scope != null) {
try {
IBinding[] bindings = scope.find(n.toString(), isPrefix);
for (int i = 0; i < bindings.length; i++) { for (int i = 0; i < bindings.length; i++) {
if (bindings[i] instanceof ICPPTemplateParameter) { if (bindings[i] instanceof ICPPClassType
|| bindings[i] instanceof IEnumeration
|| bindings[i] instanceof ICPPNamespace
|| bindings[i] instanceof ITypedef
|| bindings[i] instanceof ICPPTemplateTypeParameter) {
filtered.add(bindings[i]); 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(), isPrefix);
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 = isPrefix ?
index.findBindingsForPrefix(n.toCharArray(), filter) :
index.findBindings(n.toCharArray(), filter, new NullProgressMonitor());
for (int i = 0; i < bindings.length; i++) {
filtered.add(bindings[i]);
}
} catch (CoreException e) {
}
}
return (IBinding[]) filtered.toArray(new IBinding[filtered.size()]); return (IBinding[]) filtered.toArray(new IBinding[filtered.size()]);
} }

View file

@ -30,9 +30,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; 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.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
@ -61,9 +59,15 @@ public class CPPASTQualifiedName extends CPPASTNode implements
} }
public IASTCompletionContext getCompletionContext() { public IASTCompletionContext getCompletionContext() {
removeNullNames(); IASTNode node = getParent();
IASTName lastName = getLastName(); while (node != null) {
return lastName != null ? lastName.getCompletionContext() : null; if (node instanceof IASTCompletionContext) {
return (IASTCompletionContext) node;
}
node = node.getParent();
}
return null;
} }
/* /*
@ -304,77 +308,63 @@ public class CPPASTQualifiedName extends CPPASTNode implements
} }
public IBinding[] findBindings(IASTName n, boolean isPrefix) { public IBinding[] findBindings(IASTName n, boolean isPrefix) {
IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix);
if (names.length - 2 >= 0) {
IBinding binding = names[names.length - 2].resolveBinding(); IBinding binding = names[names.length - 2].resolveBinding();
if (binding instanceof ICPPClassType) { if (binding instanceof ICPPClassType) {
return findClassScopeBindings((ICPPClassType) binding, ICPPClassType classType = (ICPPClassType) binding;
n.toCharArray(), isPrefix); final boolean isDeclaration = getParent().getParent() instanceof IASTSimpleDeclaration;
} else if (binding instanceof ICPPNamespace) { List filtered = filterClassScopeBindings(classType, bindings, isDeclaration);
return findNamespaceScopeBindings((ICPPNamespace) binding,
n.toCharArray(), isPrefix);
}
return null;
}
private IBinding[] findClassScopeBindings(ICPPClassType classType,
char[] name, boolean isPrefix) {
List filtered = new ArrayList();
if (isDeclaration && nameMatches(classType.getNameCharArray(), n
.toCharArray(), isPrefix)) {
try { try {
ICPPClassType[] nested = classType.getNestedClasses(); ICPPConstructor[] constructors = classType.getConstructors();
for (int i = 0; i < nested.length; i++) { for (int i = 0; i < constructors.length; i++) {
char[] potential = nested[i].getNameCharArray(); if (!constructors[i].isImplicit()) {
if (nameMatches(potential, name, isPrefix)) { filtered.add(constructors[i]);
filtered.add(nested[i]);
} }
} }
} catch (DOMException e) { } catch (DOMException e) {
} }
try {
final boolean isDeclaration = getParent().getParent() instanceof IASTSimpleDeclaration;
IBinding[] bindings = classType.getCompositeScope().find(new String(name), isPrefix);
for (int i = 0; i < bindings.length; i++) {
if (bindings[i] instanceof ICPPMember) {
ICPPMember member = (ICPPMember) bindings[i];
if (!classType.isSameType(member.getClassOwner())) continue;
if (member instanceof IField) {
IField field = (IField) member;
if (!field.isStatic()) continue;
} else if (member instanceof ICPPMethod) {
ICPPMethod method = (ICPPMethod) member;
if (method.isImplicit()) continue;
if (method.isDestructor() || method instanceof ICPPConstructor) {
if (!isDeclaration) continue;
} else if (!method.isStatic() && !isDeclaration) continue;
}
} else if (!(bindings[i] instanceof IEnumerator) || isDeclaration) continue;
filtered.add(bindings[i]);
}
} catch(DOMException e) {
} }
return (IBinding[]) filtered.toArray(new IBinding[filtered.size()]); return (IBinding[]) filtered.toArray(new IBinding[filtered.size()]);
} }
}
private IBinding[] findNamespaceScopeBindings(ICPPNamespace namespace, return bindings;
char[] name, boolean isPrefix) { }
List bindings = new ArrayList();
private List filterClassScopeBindings(ICPPClassType classType,
IBinding[] bindings, final boolean isDeclaration) {
List filtered = new ArrayList();
try { try {
IBinding[] members = namespace.getMemberBindings(); for (int i = 0; i < bindings.length; i++) {
for (int i = 0 ; i < members.length; i++) { if (bindings[i] instanceof IField) {
char[] potential = members[i].getNameCharArray(); IField field = (IField) bindings[i];
if (nameMatches(potential, name, isPrefix)) { if (!field.isStatic()) continue;
bindings.add(members[i]); } else if (bindings[i] instanceof ICPPMethod) {
ICPPMethod method = (ICPPMethod) bindings[i];
if (method.isImplicit()) continue;
if (method.isDestructor() || method instanceof ICPPConstructor) {
if (!isDeclaration) continue;
} else if (!method.isStatic() && !isDeclaration) continue;
} else if (bindings[i] instanceof ICPPClassType) {
ICPPClassType type = (ICPPClassType) bindings[i];
if (type.isSameType(classType)) continue;
} else if (!(bindings[i] instanceof IEnumerator) || isDeclaration) {
continue;
} }
filtered.add(bindings[i]);
} }
} catch (DOMException e) { } catch (DOMException e) {
} }
return (IBinding[]) bindings.toArray(new IBinding[bindings.size()]); return filtered;
} }
private boolean nameMatches(char[] potential, char[] name, boolean isPrefix) { private boolean nameMatches(char[] potential, char[] name, boolean isPrefix) {

View file

@ -14,20 +14,12 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; 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.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTCompletionContext; import org.eclipse.cdt.core.dom.ast.IASTCompletionContext;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
/** /**
* @author jcamelon * @author jcamelon
@ -97,53 +89,15 @@ public class CPPASTUsingDeclaration extends CPPASTNode implements
} }
public IBinding[] findBindings(IASTName n, boolean isPrefix) { public IBinding[] findBindings(IASTName n, boolean isPrefix) {
IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix);
List filtered = new ArrayList(); 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(); for (int i = 0;i < bindings.length; i++) {
char[] nChars = n.toCharArray(); if (bindings[i] instanceof ICPPNamespace) {
for (int i = 0; i < decls.length; i++) {
if (decls[i] instanceof ICPPASTNamespaceDefinition) {
ICPPASTNamespaceDefinition defn = (ICPPASTNamespaceDefinition) decls[i];
IASTName name = defn.getName();
if (nameMatches(name.toCharArray(), nChars, isPrefix)) {
IBinding binding = name.resolveBinding();
if (filter.acceptBinding(binding)) {
filtered.add(binding);
}
}
}
}
IIndex index = getTranslationUnit().getIndex();
if (index != null) {
try {
IBinding[] bindings = isPrefix ?
index.findBindingsForPrefix(n.toCharArray(), filter) :
index.findBindings(n.toCharArray(), filter, new NullProgressMonitor());
for (int i = 0; i < bindings.length; i++) {
filtered.add(bindings[i]); filtered.add(bindings[i]);
} }
} catch (CoreException e) {
}
} }
return (IBinding[]) filtered.toArray(new IBinding[filtered.size()]); return (IBinding[]) filtered.toArray(new IBinding[filtered.size()]);
} }
private boolean nameMatches(char[] potential, char[] name, boolean isPrefix) {
if (isPrefix) {
return CharArrayUtils.equals(potential, 0, name.length, name, false);
} else {
return CharArrayUtils.equals(potential, name);
}
}
} }

View file

@ -14,20 +14,12 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; 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.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTCompletionContext; import org.eclipse.cdt.core.dom.ast.IASTCompletionContext;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; 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.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
/** /**
* @author jcamelon * @author jcamelon
@ -82,53 +74,15 @@ public class CPPASTUsingDirective extends CPPASTNode implements
} }
public IBinding[] findBindings(IASTName n, boolean isPrefix) { public IBinding[] findBindings(IASTName n, boolean isPrefix) {
IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix);
List filtered = new ArrayList(); 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(); for (int i = 0;i < bindings.length; i++) {
char[] nChars = n.toCharArray(); if (bindings[i] instanceof ICPPNamespace) {
for (int i = 0; i < decls.length; i++) {
if (decls[i] instanceof ICPPASTNamespaceDefinition) {
ICPPASTNamespaceDefinition defn = (ICPPASTNamespaceDefinition) decls[i];
IASTName name = defn.getName();
if (nameMatches(name.toCharArray(), nChars, isPrefix)) {
IBinding binding = name.resolveBinding();
if (filter.acceptBinding(binding)) {
filtered.add(binding);
}
}
}
}
IIndex index = getTranslationUnit().getIndex();
if (index != null) {
try {
IBinding[] bindings = isPrefix ?
index.findBindingsForPrefix(n.toCharArray(), filter) :
index.findBindings(n.toCharArray(), filter, new NullProgressMonitor());
for (int i = 0; i < bindings.length; i++) {
filtered.add(bindings[i]); filtered.add(bindings[i]);
} }
} catch (CoreException e) {
}
} }
return (IBinding[]) filtered.toArray(new IBinding[filtered.size()]); return (IBinding[]) filtered.toArray(new IBinding[filtered.size()]);
} }
private boolean nameMatches(char[] potential, char[] name, boolean isPrefix) {
if (isPrefix) {
return CharArrayUtils.equals(potential, 0, name.length, name, false);
} else {
return CharArrayUtils.equals(potential, name);
}
}
} }

View file

@ -16,6 +16,7 @@
*/ */
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression; import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
@ -92,7 +93,6 @@ 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.ICPPASTWhileStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; 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.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.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
@ -121,6 +121,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
@ -133,6 +134,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.index.IIndexScope; import org.eclipse.cdt.internal.core.index.IIndexScope;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
/** /**
* @author aniefer * @author aniefer
@ -159,6 +161,7 @@ public class CPPSemantics {
public boolean forceQualified = false; public boolean forceQualified = false;
public boolean forUserDefinedConversion = false; public boolean forUserDefinedConversion = false;
public boolean forAssociatedScopes = false; public boolean forAssociatedScopes = false;
public boolean contentAssist = false;
public boolean prefixLookup = false; public boolean prefixLookup = false;
public boolean typesOnly = false; public boolean typesOnly = false;
public boolean considerConstructors = false; public boolean considerConstructors = false;
@ -926,7 +929,7 @@ public class CPPSemantics {
return new CPPScope.CPPScopeProblem( name, IProblemBinding.SEMANTIC_BAD_SCOPE, name.toCharArray() ); return new CPPScope.CPPScopeProblem( name, IProblemBinding.SEMANTIC_BAD_SCOPE, name.toCharArray() );
} }
private static void mergeResults( LookupData data, Object results, boolean scoped ){ private static void mergeResults( LookupData data, Object results, boolean scoped ){
if( !data.prefixLookup ){ if( !data.contentAssist ){
if( results instanceof IBinding ){ if( results instanceof IBinding ){
data.foundItems = ArrayUtil.append( Object.class, (Object[]) data.foundItems, results ); data.foundItems = ArrayUtil.append( Object.class, (Object[]) data.foundItems, results );
} else if( results instanceof Object[] ){ } else if( results instanceof Object[] ){
@ -1015,53 +1018,70 @@ public class CPPSemantics {
ArrayWrapper directives = null; ArrayWrapper directives = null;
if( !data.usingDirectivesOnly ){ if( !data.usingDirectivesOnly ){
if( ASTInternal.isFullyCached(scope) && !data.prefixLookup && data.astName != null ){ if( ASTInternal.isFullyCached(scope) && !data.contentAssist && data.astName != null ){
IBinding binding = data.prefixLookup ? null : scope.getBinding( data.astName, true ); IBinding binding = data.contentAssist ? null : scope.getBinding( data.astName, true );
if( binding != null && if( binding != null &&
( CPPSemantics.declaredBefore( binding, data.astName ) || ( CPPSemantics.declaredBefore( binding, data.astName ) ||
(scope instanceof ICPPClassScope && data.checkWholeClassScope) ) ) (scope instanceof ICPPClassScope && data.checkWholeClassScope) ) )
{ {
mergeResults( data, binding, true ); mergeResults( data, binding, true );
} }
} else { } else if (data.astName != null) {
IBinding b= null; boolean useASTResults = true;
if (!data.prefixLookup && data.astName != null ) { IBinding b = null;
if (!data.contentAssist) {
b= scope.getBinding( data.astName, false ); b= scope.getBinding( data.astName, false );
if (b instanceof CPPImplicitFunction || b instanceof CPPImplicitTypedef) if (b instanceof CPPImplicitFunction || b instanceof CPPImplicitTypedef)
mergeResults( data, b, true ); mergeResults( data, b, true );
} else if (data.prefixLookup && data.astName != null) { } else {
IASTNode parent = ASTInternal.getPhysicalNodeOfScope(scope); IASTNode parent = ASTInternal.getPhysicalNodeOfScope(scope);
if (parent == null && scope instanceof IIndexScope) { if (parent == null) {
IBinding[] bindings = scope.find(data.astName.toString(), data.prefixLookup); IBinding[] bindings = scope.find(data.astName.toString(), data.prefixLookup);
mergeResults(data, bindings, true); mergeResults(data, bindings, true);
} else if (scope instanceof ICPPNamespaceScope && !(scope instanceof ICPPBlockScope)) { useASTResults = false;
ICPPNamespaceScope ns = (ICPPNamespaceScope) scope; } else {
IIndex index = parent.getTranslationUnit().getIndex(); IIndex index = parent.getTranslationUnit().getIndex();
if (index != null) { if (index != null) {
if (parent instanceof IASTTranslationUnit) {
try { try {
IIndexBinding binding = index.findBinding(ns.getScopeName()); IndexFilter filter = IndexFilter.getFilter(ILinkage.CPP_LINKAGE_ID);
IBinding[] bindings = data.prefixLookup ?
index.findBindingsForPrefix(data.astName.toCharArray(), filter) :
index.findBindings(data.astName.toCharArray(), filter, new NullProgressMonitor());
mergeResults(data, bindings, true);
useASTResults = false;
} catch (CoreException e) {
}
} else if (parent instanceof ICPPASTNamespaceDefinition) {
ICPPASTNamespaceDefinition ns = (ICPPASTNamespaceDefinition) parent;
try {
IIndexBinding binding = index.findBinding(ns.getName());
if (binding instanceof ICPPNamespace) { if (binding instanceof ICPPNamespace) {
ICPPNamespaceScope indexNs = ((ICPPNamespace)binding).getNamespaceScope(); ICPPNamespaceScope indexNs = ((ICPPNamespace)binding).getNamespaceScope();
IBinding[] bindings = indexNs.find(data.astName.toString(), data.prefixLookup); IBinding[] bindings = indexNs.find(data.astName.toString(), data.prefixLookup);
mergeResults(data, bindings, true); mergeResults(data, bindings, true);
useASTResults = false;
} }
} catch (CoreException e) { } catch (CoreException e) {
} }
} }
} }
} }
}
IASTName[] inScope = lookupInScope( data, scope, blockItem ); IASTName[] inScope = lookupInScope( data, scope, blockItem );
// must call lookupInScope(...) even if the index results
// have already been used in order to handle using directives
if (useASTResults) {
if (inScope != null) { if (inScope != null) {
mergeResults( data, inScope, true ); mergeResults( data, inScope, true );
} else if (b instanceof IIndexBinding) {
mergeResults( data, b, true);
} }
else if (b instanceof IIndexBinding) {
// since the ast did not come up with a binding, use what
// we have found in the index.
mergeResults(data, b, true);
} }
} }
if( (!data.hasResults() || data.prefixLookup) && scope instanceof ICPPNamespaceScope ){ if( (!data.hasResults() || data.contentAssist) && scope instanceof ICPPNamespaceScope ){
directives = new ArrayWrapper(); directives = new ArrayWrapper();
directives.array = ((ICPPNamespaceScope) scope).getUsingDirectives(); directives.array = ((ICPPNamespaceScope) scope).getUsingDirectives();
if( directives.array != null ){ if( directives.array != null ){
@ -1077,7 +1097,7 @@ public class CPPSemantics {
if( !data.ignoreUsingDirectives ) { if( !data.ignoreUsingDirectives ) {
data.visited.clear(); data.visited.clear();
if( data.prefixLookup || !data.hasResults() ){ if( data.contentAssist || !data.hasResults() ){
Object[] transitives = lookupInNominated( data, scope, null ); Object[] transitives = lookupInNominated( data, scope, null );
processDirectives( data, scope, transitives ); processDirectives( data, scope, transitives );
@ -1087,14 +1107,14 @@ public class CPPSemantics {
while( !data.usingDirectives.isEmpty() && data.usingDirectives.get( scope ) != null ){ while( !data.usingDirectives.isEmpty() && data.usingDirectives.get( scope ) != null ){
transitives = lookupInNominated( data, scope, transitives ); transitives = lookupInNominated( data, scope, transitives );
if( !data.qualified() || ( data.prefixLookup || !data.hasResults()) ){ if( !data.qualified() || ( data.contentAssist || !data.hasResults()) ){
processDirectives( data, scope, transitives ); processDirectives( data, scope, transitives );
} }
} }
} }
} }
if( (!data.prefixLookup && (data.problem != null || data.hasResults())) || if( (!data.contentAssist && (data.problem != null || data.hasResults())) ||
( friendInLocalClass && !(scope instanceof ICPPClassScope) ) ) ( friendInLocalClass && !(scope instanceof ICPPClassScope) ) )
{ {
return; return;
@ -1104,7 +1124,7 @@ public class CPPSemantics {
mergeResults( data, lookupInParents( data, scope ), true ); mergeResults( data, lookupInParents( data, scope ), true );
} }
if( !data.prefixLookup && (data.problem != null || data.hasResults()) ) if( !data.contentAssist && (data.problem != null || data.hasResults()) )
return; return;
//if still not found, loop and check our containing scope //if still not found, loop and check our containing scope
@ -1192,12 +1212,15 @@ public class CPPSemantics {
//is circular inheritance //is circular inheritance
if( ! data.inheritanceChain.containsKey( parent ) ){ if( ! data.inheritanceChain.containsKey( parent ) ){
//is this name define in this scope? //is this name define in this scope?
if( data.astName != null && !data.prefixLookup && ASTInternal.isFullyCached(parent) ) if( data.astName != null && !data.contentAssist && ASTInternal.isFullyCached(parent) )
inherited = parent.getBinding( data.astName, true ); inherited = parent.getBinding( data.astName, true );
else if (ASTInternal.getPhysicalNodeOfScope(lookIn) != null
&& ASTInternal.getPhysicalNodeOfScope(parent) == null)
inherited = parent.find(data.astName.toString(), data.prefixLookup);
else else
inherited = lookupInScope( data, parent, null ); inherited = lookupInScope( data, parent, null );
if( inherited == null || data.prefixLookup ){ if( inherited == null || data.contentAssist ){
Object temp = lookupInParents( data, parent ); Object temp = lookupInParents( data, parent );
if( inherited != null ){ if( inherited != null ){
inherited = mergePrefixResults( null, inherited, true ); inherited = mergePrefixResults( null, inherited, true );
@ -1218,7 +1241,7 @@ public class CPPSemantics {
if( result == null ){ if( result == null ){
result = inherited; result = inherited;
} else if ( inherited != null ) { } else if ( inherited != null ) {
if( !data.prefixLookup ) { if( !data.contentAssist ) {
if( result instanceof Object [] ){ if( result instanceof Object [] ){
Object [] r = (Object[]) result; Object [] r = (Object[]) result;
for( int j = 0; j < r.length && r[j] != null; j++ ) { for( int j = 0; j < r.length && r[j] != null; j++ ) {
@ -1582,7 +1605,7 @@ public class CPPSemantics {
ArrayWrapper usings = new ArrayWrapper(); ArrayWrapper usings = new ArrayWrapper();
boolean found = false; boolean found = false;
if( ASTInternal.isFullyCached(temp) && !data.prefixLookup ){ if( ASTInternal.isFullyCached(temp) && !data.contentAssist ){
IBinding binding = temp.getBinding( data.astName, true ); IBinding binding = temp.getBinding( data.astName, true );
if( binding != null && if( binding != null &&
( CPPSemantics.declaredBefore( binding, data.astName ) || ( CPPSemantics.declaredBefore( binding, data.astName ) ||
@ -1591,6 +1614,12 @@ public class CPPSemantics {
mergeResults( data, binding, true ); mergeResults( data, binding, true );
found = true; found = true;
} }
} else if (ASTInternal.getPhysicalNodeOfScope(temp) == null) {
IBinding[] bindings = temp.find(data.astName.toString(), data.prefixLookup);
if (bindings != null && bindings.length > 0) {
mergeResults( data, bindings, true );
found = true;
}
} else { } else {
IASTName [] f = lookupInScope( data, temp, null ); IASTName [] f = lookupInScope( data, temp, null );
if( f != null ) { if( f != null ) {
@ -1928,7 +1957,7 @@ public class CPPSemantics {
} }
static private IBinding resolveAmbiguities( CPPSemantics.LookupData data, IASTName name ) throws DOMException { static private IBinding resolveAmbiguities( CPPSemantics.LookupData data, IASTName name ) throws DOMException {
if( !data.hasResults() || data.prefixLookup ) if( !data.hasResults() || data.contentAssist )
return null; return null;
IBinding type = null; IBinding type = null;
@ -3280,6 +3309,7 @@ public class CPPSemantics {
public static IBinding[] findBindings( IScope scope, String name, boolean qualified, boolean prefixLookup ) throws DOMException{ public static IBinding[] findBindings( IScope scope, String name, boolean qualified, boolean prefixLookup ) throws DOMException{
return findBindings( scope, name.toCharArray(), qualified, prefixLookup ); return findBindings( scope, name.toCharArray(), qualified, prefixLookup );
} }
public static IBinding[] findBindings( IScope scope, char []name, boolean qualified, boolean prefixLookup ) throws DOMException{ public static IBinding[] findBindings( IScope scope, char []name, boolean qualified, boolean prefixLookup ) throws DOMException{
CPPASTName astName = new CPPASTName(); CPPASTName astName = new CPPASTName();
astName.setName( name ); astName.setName( name );
@ -3287,54 +3317,30 @@ public class CPPSemantics {
astName.setPropertyInParent( STRING_LOOKUP_PROPERTY ); astName.setPropertyInParent( STRING_LOOKUP_PROPERTY );
if (prefixLookup) { if (prefixLookup) {
return prefixLookup(astName, scope); LookupData data = createLookupData( astName, true );
} data.contentAssist = true;
LookupData data = new LookupData( astName );
data.forceQualified = qualified;
try {
lookup( data, scope );
} catch (DOMException e) {
return new IBinding [] { e.getProblem() };
}
Object [] items = (Object[]) data.foundItems;
if( items == null )
return new IBinding[0];
ObjectSet set = new ObjectSet( items.length );
IBinding binding = null;
for( int i = 0; i < items.length; i++ ){
if( items[i] instanceof IASTName )
binding = ((IASTName) items[i]).resolveBinding();
else if( items[i] instanceof IBinding )
binding = (IBinding) items[i];
else
binding = null;
if( binding != null )
if( binding instanceof ICPPUsingDeclaration ){
set.addAll( ((ICPPUsingDeclaration)binding).getDelegates() );
} else if( binding instanceof CPPCompositeBinding ){
set.addAll( ((CPPCompositeBinding)binding).getBindings() );
} else {
set.put( binding );
}
}
return (IBinding[]) set.keyArray( IBinding.class );
}
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.prefixLookup = true;
data.foundItems = new CharArrayObjectMap( 2 ); data.foundItems = new CharArrayObjectMap( 2 );
data.forceQualified = qualified;
return contentAssistLookup(data, scope);
} else {
LookupData data = new LookupData( astName );
data.forceQualified = qualified;
return standardLookup(data, scope);
}
}
public static IBinding[] findBindingsForContentAssist(IASTName name, boolean prefixLookup) {
LookupData data = createLookupData(name, true);
data.contentAssist = true;
data.prefixLookup = prefixLookup;
data.foundItems = new CharArrayObjectMap(2);
return contentAssistLookup(data, name);
}
private static IBinding [] contentAssistLookup( LookupData data, Object start ){
try { try {
lookup( data, start ); lookup( data, start );
} catch ( DOMException e ) { } catch ( DOMException e ) {
@ -3373,6 +3379,43 @@ public class CPPSemantics {
return (IBinding[]) ArrayUtil.trim( IBinding.class, result ); return (IBinding[]) ArrayUtil.trim( IBinding.class, result );
} }
private static IBinding [] standardLookup( LookupData data, Object start ) {
try {
lookup( data, start );
} catch (DOMException e) {
return new IBinding [] { e.getProblem() };
}
Object [] items = (Object[]) data.foundItems;
if( items == null )
return new IBinding[0];
ObjectSet set = new ObjectSet( items.length );
IBinding binding = null;
for( int i = 0; i < items.length; i++ ){
if( items[i] instanceof IASTName )
binding = ((IASTName) items[i]).resolveBinding();
else if( items[i] instanceof IBinding )
binding = (IBinding) items[i];
else
binding = null;
if( binding != null )
if( binding instanceof ICPPUsingDeclaration ){
try {
set.addAll( ((ICPPUsingDeclaration)binding).getDelegates() );
} catch (DOMException e) {
}
} else if( binding instanceof CPPCompositeBinding ){
set.addAll( ((CPPCompositeBinding)binding).getBindings() );
} else {
set.put( binding );
}
}
return (IBinding[]) set.keyArray( IBinding.class );
}
public static boolean isSameFunction(IFunction function, IASTDeclarator declarator) { public static boolean isSameFunction(IFunction function, IASTDeclarator declarator) {
IASTName name = declarator.getName(); IASTName name = declarator.getName();
ICPPASTTemplateDeclaration templateDecl = CPPTemplates.getTemplateDeclaration( name ); ICPPASTTemplateDeclaration templateDecl = CPPTemplates.getTemplateDeclaration( name );

View file

@ -193,6 +193,9 @@ ICPPClassScope, IPDOMMemberOwner, IIndexType, IIndexScope {
return; return;
visited.add(this); visited.add(this);
// Class is in its own scope
visitor.visit(this);
// Get my members // Get my members
accept(visitor); accept(visitor);

View file

@ -31,7 +31,6 @@ public class CompletionTest_ClassReference_NoPrefix extends CompletionProposals
private final String[] expectedResults = { private final String[] expectedResults = {
"aClass", "aClass",
"anotherClass", "anotherClass",
"ClassA",
"xOtherClass" "xOtherClass"
}; };

View file

@ -308,6 +308,22 @@ public class CompletionTests extends AbstractContentAssistTest {
assertCompletionResults(fCursorOffset, expected, true); assertCompletionResults(fCursorOffset, expected, true);
} }
//namespace ns {void nsfunc(){C/*cursor*/
public void testTypes_NamespaceScope() throws Exception {
final String[] expected= {
"C1", "C2", "C3", "CNS"
};
assertCompletionResults(fCursorOffset, expected, true);
}
//namespace ns {void gfunc(){::C/*cursor*/
public void testTypes_GlobalQualification() throws Exception {
final String[] expected= {
"C1", "C2", "C3"
};
assertCompletionResults(fCursorOffset, expected, true);
}
//void f() {e/*cursor*/ //void f() {e/*cursor*/
public void testEnums_GlobalScope() throws Exception { public void testEnums_GlobalScope() throws Exception {
final String[] expected= { final String[] expected= {
@ -585,4 +601,12 @@ public class CompletionTests extends AbstractContentAssistTest {
}; };
assertCompletionResults(fCursorOffset, expected, true); assertCompletionResults(fCursorOffset, expected, true);
} }
//using namespace ns;void gfunc(){NSC/*cursor*/
public void testUsingDirective() throws Exception {
final String[] expected= {
"NSCONST"
};
assertCompletionResults(fCursorOffset, expected, true);
}
} }

View file

@ -70,7 +70,7 @@ public class ParameterHintTests extends AbstractContentAssistTest {
////TODO move function into header once indexer supports templates ////TODO move function into header once indexer supports templates
//template<class T>void tFunc(T x, T y); //template<class T>void tFunc(T x, T y);
//void foo(){tFunc( //void foo(){tFunc(
public void testTemplateFunction() throws Exception { public void _testTemplateFunction() throws Exception {
assertParameterHints(new String[] { assertParameterHints(new String[] {
"tFunc(T x,T y) void" "tFunc(T x,T y) void"
}); });
@ -158,7 +158,7 @@ public class ParameterHintTests extends AbstractContentAssistTest {
}); });
} }
//void foo(){int pi = 3;pi( //int pi = 3;void foo(){pi(
public void testFunctionsOnly() throws Exception { public void testFunctionsOnly() throws Exception {
assertParameterHints(new String[] { assertParameterHints(new String[] {
"pi(aClass a) int" "pi(aClass a) int"

View file

@ -117,6 +117,10 @@ public class CContentAssistInvocationContext extends ContentAssistInvocationCont
if (proj == null) return null; if (proj == null) return null;
try{ try{
IPDOMManager manager = CCorePlugin.getPDOMManager();
String indexerId = manager.getIndexerId(proj);
if (!IPDOMManager.ID_NO_INDEXER.equals(indexerId)) {
fIndex = CCorePlugin.getIndexManager().getIndex(proj, fIndex = CCorePlugin.getIndexManager().getIndex(proj,
IIndexManager.ADD_DEPENDENCIES | IIndexManager.ADD_DEPENDENT); IIndexManager.ADD_DEPENDENCIES | IIndexManager.ADD_DEPENDENT);
@ -125,11 +129,10 @@ public class CContentAssistInvocationContext extends ContentAssistInvocationCont
} catch (InterruptedException e) { } catch (InterruptedException e) {
fIndex = null; fIndex = null;
} }
}
IPDOMManager manager = CCorePlugin.getPDOMManager();
String indexerId = manager.getIndexerId(proj);
int flags = ITranslationUnit.AST_SKIP_ALL_HEADERS; int flags = ITranslationUnit.AST_SKIP_ALL_HEADERS;
if (fIndex == null || IPDOMManager.ID_NO_INDEXER.equals(indexerId)) { if (fIndex == null) {
flags = 0; flags = 0;
} }