mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-23 17:05:26 +02:00
Fix for Bug 174840 - IASTCompletionContext finds duplicate bindings (Patch by Bryan Wilkinson)
This commit is contained in:
parent
335ae395bd
commit
71628f81e4
18 changed files with 313 additions and 595 deletions
|
@ -2169,7 +2169,7 @@ public class AST2CPPTests extends AST2BaseTest {
|
|||
tu.accept(col);
|
||||
|
||||
IASTName name = col.getName(11);
|
||||
IBinding[] bs = CPPSemantics.prefixLookup(name);
|
||||
IBinding[] bs = CPPSemantics.findBindingsForContentAssist(name, true);
|
||||
assertEquals(4, bs.length);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,23 +12,15 @@
|
|||
*******************************************************************************/
|
||||
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.IASTCompletionContext;
|
||||
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.cpp.CPPSemantics;
|
||||
|
||||
/**
|
||||
* @author jcamelon
|
||||
|
@ -105,37 +97,6 @@ public class CASTFieldReference extends CASTNode implements IASTFieldReference,
|
|||
}
|
||||
|
||||
public IBinding[] findBindings(IASTName n, boolean isPrefix) {
|
||||
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 (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);
|
||||
}
|
||||
return CVisitor.findBindingsForContentAssist(n, isPrefix);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,20 +12,12 @@
|
|||
*******************************************************************************/
|
||||
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.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTCompletionContext;
|
||||
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.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||
|
||||
/**
|
||||
* @author jcamelon
|
||||
|
@ -73,33 +65,6 @@ public class CASTIdExpression extends CASTNode implements IASTIdExpression, IAST
|
|||
}
|
||||
|
||||
public IBinding[] findBindings(IASTName n, boolean isPrefix) {
|
||||
IScope scope = CVisitor.getContainingScope(n);
|
||||
|
||||
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;
|
||||
return CVisitor.findBindingsForContentAssist(n, isPrefix);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,21 +15,14 @@ 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.IASTCompletionContext;
|
||||
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.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||
|
||||
/**
|
||||
* @author jcamelon
|
||||
|
@ -80,45 +73,14 @@ public class CASTTypedefNameSpecifier extends CASTBaseDeclSpecifier implements
|
|||
}
|
||||
|
||||
public IBinding[] findBindings(IASTName n, boolean isPrefix) {
|
||||
IBinding[] bindings = CVisitor.findBindingsForContentAssist(n, isPrefix);
|
||||
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++) {
|
||||
filtered.add(bindings[i]);
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
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.DOMException;
|
||||
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.IGCCASTSimpleDeclSpecifier;
|
||||
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.CharArrayObjectMap;
|
||||
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.ProblemBinding;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||
|
||||
/**
|
||||
* Created on Nov 5, 2004
|
||||
|
@ -1194,8 +1197,14 @@ public class CVisitor {
|
|||
}
|
||||
} else if ( parent instanceof IASTTranslationUnit ){
|
||||
IASTTranslationUnit translation = (IASTTranslationUnit) parent;
|
||||
nodes = translation.getDeclarations();
|
||||
scope = (ICScope) translation.getScope();
|
||||
if (!prefix || translation.getIndex() == null) {
|
||||
nodes = translation.getDeclarations();
|
||||
scope = (ICScope) translation.getScope();
|
||||
} else {
|
||||
//The index will be search later
|
||||
nodes = null;
|
||||
scope = null;
|
||||
}
|
||||
} else if( parent instanceof IASTStandardFunctionDeclarator ){
|
||||
IASTStandardFunctionDeclarator dtor = (IASTStandardFunctionDeclarator) parent;
|
||||
nodes = dtor.getParameters();
|
||||
|
@ -1306,6 +1315,24 @@ public class CVisitor {
|
|||
for ( int i = 0; i < vals.length; i++ ) {
|
||||
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 );
|
||||
}
|
||||
if( blockItem != null) {
|
||||
|
@ -1899,15 +1926,15 @@ public class CVisitor {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static IBinding [] prefixLookup( IASTName name ){
|
||||
public static IBinding [] findBindingsForContentAssist( IASTName name, boolean isPrefix ){
|
||||
ASTNodeProperty prop = name.getPropertyInParent();
|
||||
|
||||
IBinding [] result = null;
|
||||
|
||||
if( prop == IASTFieldReference.FIELD_NAME ){
|
||||
result = (IBinding[]) findBinding( (IASTFieldReference) name.getParent(), true );
|
||||
result = (IBinding[]) findBinding( (IASTFieldReference) name.getParent(), isPrefix );
|
||||
} else {
|
||||
int bits = PREFIX_LOOKUP;
|
||||
int bits = isPrefix ? PREFIX_LOOKUP : COMPLETE;
|
||||
if( prop == IASTElaboratedTypeSpecifier.TYPE_NAME ){
|
||||
bits |= TAGS;
|
||||
} else if( prop == IASTIdExpression.ID_NAME ){
|
||||
|
@ -1916,7 +1943,8 @@ public class CVisitor {
|
|||
|
||||
IASTNode blockItem = getContainingBlockItem( name );
|
||||
try {
|
||||
result = (IBinding[]) findBinding( blockItem, name, bits );
|
||||
result = isPrefix ? (IBinding[]) findBinding( blockItem, name, bits ) :
|
||||
new IBinding[] { (IBinding) findBinding( blockItem, name, bits ) };
|
||||
} catch ( DOMException e ) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,20 +14,14 @@ 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.IASTCompletionContext;
|
||||
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.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||
|
||||
/**
|
||||
* @author jcamelon
|
||||
|
@ -113,54 +107,33 @@ public class CPPASTBaseSpecifier extends CPPASTNode implements
|
|||
}
|
||||
|
||||
public IBinding[] findBindings(IASTName n, boolean isPrefix) {
|
||||
IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix);
|
||||
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(), 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) {
|
||||
ICPPClassType classType = null;
|
||||
if (getParent() instanceof CPPASTCompositeTypeSpecifier) {
|
||||
IASTName className = ((CPPASTCompositeTypeSpecifier) getParent()).getName();
|
||||
IBinding binding = className.resolveBinding();
|
||||
if (binding instanceof ICPPClassType) {
|
||||
classType = (ICPPClassType) binding;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (int i = 0; i < bindings.length; i++) {
|
||||
if (bindings[i] instanceof ICPPClassType) {
|
||||
ICPPClassType base = (ICPPClassType) bindings[i];
|
||||
try {
|
||||
int key = base.getKey();
|
||||
if (key == ICPPClassType.k_class &&
|
||||
(classType == null || !base.isSameType(classType))) {
|
||||
filtered.add(base);
|
||||
}
|
||||
} catch (DOMException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (IBinding[]) filtered.toArray(new IBinding[filtered.size()]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,20 +15,14 @@ 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.IASTCompletionContext;
|
||||
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;
|
||||
|
||||
/**
|
||||
|
@ -116,73 +110,19 @@ public class CPPASTFieldReference extends CPPASTNode implements
|
|||
}
|
||||
|
||||
public IBinding[] findBindings(IASTName n, boolean isPrefix) {
|
||||
IASTExpression expression = getFieldOwner();
|
||||
IType type = expression.getExpressionType();
|
||||
type = CPPSemantics.getUltimateType(type, true); //stop at pointer to member?
|
||||
IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix);
|
||||
List filtered = new ArrayList();
|
||||
|
||||
if (type instanceof ICPPClassType) {
|
||||
ICPPClassType classType = (ICPPClassType) type;
|
||||
List bindings = new ArrayList();
|
||||
char[] name = n.toCharArray();
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (DOMException e) {
|
||||
}
|
||||
|
||||
try {
|
||||
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);
|
||||
for (int i = 0; i < bindings.length; i++) {
|
||||
if (bindings[i] instanceof ICPPMethod) {
|
||||
ICPPMethod method = (ICPPMethod) bindings[i];
|
||||
if (method.isImplicit()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} 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);
|
||||
filtered.add(bindings[i]);
|
||||
}
|
||||
|
||||
return (IBinding[]) filtered.toArray(new IBinding[filtered.size()]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,20 +11,12 @@
|
|||
*******************************************************************************/
|
||||
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.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTCompletionContext;
|
||||
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.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||
|
||||
/**
|
||||
* @author jcamelon
|
||||
|
@ -71,33 +63,6 @@ public class CPPASTIdExpression extends CPPASTNode implements IASTIdExpression,
|
|||
}
|
||||
|
||||
public IBinding[] findBindings(IASTName n, boolean isPrefix) {
|
||||
IScope scope = CPPVisitor.getContainingScope(n);
|
||||
|
||||
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;
|
||||
return CPPSemantics.findBindingsForContentAssist(n, isPrefix);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,23 +14,16 @@ 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.IASTCompletionContext;
|
||||
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.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
|
||||
|
||||
/**
|
||||
* @author jcamelon
|
||||
|
@ -99,56 +92,17 @@ public class CPPASTNamedTypeSpecifier extends CPPASTBaseDeclSpecifier implements
|
|||
}
|
||||
|
||||
public IBinding[] findBindings(IASTName n, boolean isPrefix) {
|
||||
IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix);
|
||||
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++) {
|
||||
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;
|
||||
for (int i = 0; i < bindings.length; i++) {
|
||||
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]);
|
||||
}
|
||||
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()]);
|
||||
|
|
|
@ -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.ICPPClassType;
|
||||
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.ICPPNamespace;
|
||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||
|
||||
|
@ -61,9 +59,15 @@ public class CPPASTQualifiedName extends CPPASTNode implements
|
|||
}
|
||||
|
||||
public IASTCompletionContext getCompletionContext() {
|
||||
removeNullNames();
|
||||
IASTName lastName = getLastName();
|
||||
return lastName != null ? lastName.getCompletionContext() : null;
|
||||
IASTNode node = getParent();
|
||||
while (node != 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) {
|
||||
IBinding binding = names[names.length - 2].resolveBinding();
|
||||
if (binding instanceof ICPPClassType) {
|
||||
return findClassScopeBindings((ICPPClassType) binding,
|
||||
n.toCharArray(), isPrefix);
|
||||
} else if (binding instanceof ICPPNamespace) {
|
||||
return findNamespaceScopeBindings((ICPPNamespace) binding,
|
||||
n.toCharArray(), isPrefix);
|
||||
}
|
||||
IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix);
|
||||
|
||||
return null;
|
||||
if (names.length - 2 >= 0) {
|
||||
IBinding binding = names[names.length - 2].resolveBinding();
|
||||
if (binding instanceof ICPPClassType) {
|
||||
ICPPClassType classType = (ICPPClassType) binding;
|
||||
final boolean isDeclaration = getParent().getParent() instanceof IASTSimpleDeclaration;
|
||||
List filtered = filterClassScopeBindings(classType, bindings, isDeclaration);
|
||||
|
||||
if (isDeclaration && nameMatches(classType.getNameCharArray(), n
|
||||
.toCharArray(), isPrefix)) {
|
||||
try {
|
||||
ICPPConstructor[] constructors = classType.getConstructors();
|
||||
for (int i = 0; i < constructors.length; i++) {
|
||||
if (!constructors[i].isImplicit()) {
|
||||
filtered.add(constructors[i]);
|
||||
}
|
||||
}
|
||||
} catch (DOMException e) {
|
||||
}
|
||||
}
|
||||
|
||||
return (IBinding[]) filtered.toArray(new IBinding[filtered.size()]);
|
||||
}
|
||||
}
|
||||
|
||||
return bindings;
|
||||
}
|
||||
|
||||
private IBinding[] findClassScopeBindings(ICPPClassType classType,
|
||||
char[] name, boolean isPrefix) {
|
||||
private List filterClassScopeBindings(ICPPClassType classType,
|
||||
IBinding[] bindings, final boolean isDeclaration) {
|
||||
List filtered = new ArrayList();
|
||||
|
||||
try {
|
||||
ICPPClassType[] nested = classType.getNestedClasses();
|
||||
for (int i = 0; i < nested.length; i++) {
|
||||
char[] potential = nested[i].getNameCharArray();
|
||||
if (nameMatches(potential, name, isPrefix)) {
|
||||
filtered.add(nested[i]);
|
||||
}
|
||||
}
|
||||
} 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;
|
||||
if (bindings[i] instanceof IField) {
|
||||
IField field = (IField) bindings[i];
|
||||
if (!field.isStatic()) continue;
|
||||
} 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) {
|
||||
}
|
||||
|
||||
return (IBinding[]) filtered.toArray(new IBinding[filtered.size()]);
|
||||
}
|
||||
|
||||
private IBinding[] findNamespaceScopeBindings(ICPPNamespace namespace,
|
||||
char[] name, boolean isPrefix) {
|
||||
List bindings = new ArrayList();
|
||||
|
||||
try {
|
||||
IBinding[] members = namespace.getMemberBindings();
|
||||
for (int i = 0 ; i < members.length; i++) {
|
||||
char[] potential = members[i].getNameCharArray();
|
||||
if (nameMatches(potential, name, isPrefix)) {
|
||||
bindings.add(members[i]);
|
||||
}
|
||||
}
|
||||
} catch (DOMException e) {
|
||||
}
|
||||
|
||||
return (IBinding[]) bindings.toArray(new IBinding[bindings.size()]);
|
||||
return filtered;
|
||||
}
|
||||
|
||||
private boolean nameMatches(char[] potential, char[] name, boolean isPrefix) {
|
||||
|
|
|
@ -14,20 +14,12 @@ 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.IASTCompletionContext;
|
||||
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.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||
|
||||
/**
|
||||
* @author jcamelon
|
||||
|
@ -97,53 +89,15 @@ public class CPPASTUsingDeclaration extends CPPASTNode implements
|
|||
}
|
||||
|
||||
public IBinding[] findBindings(IASTName n, boolean isPrefix) {
|
||||
IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix);
|
||||
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 (nameMatches(name.toCharArray(), nChars, isPrefix)) {
|
||||
IBinding binding = name.resolveBinding();
|
||||
if (filter.acceptBinding(binding)) {
|
||||
filtered.add(binding);
|
||||
}
|
||||
}
|
||||
for (int i = 0;i < bindings.length; i++) {
|
||||
if (bindings[i] instanceof ICPPNamespace) {
|
||||
filtered.add(bindings[i]);
|
||||
}
|
||||
}
|
||||
|
||||
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()]);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,20 +14,12 @@ 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.IASTCompletionContext;
|
||||
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.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||
|
||||
/**
|
||||
* @author jcamelon
|
||||
|
@ -82,53 +74,15 @@ public class CPPASTUsingDirective extends CPPASTNode implements
|
|||
}
|
||||
|
||||
public IBinding[] findBindings(IASTName n, boolean isPrefix) {
|
||||
IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix);
|
||||
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 (nameMatches(name.toCharArray(), nChars, isPrefix)) {
|
||||
IBinding binding = name.resolveBinding();
|
||||
if (filter.acceptBinding(binding)) {
|
||||
filtered.add(binding);
|
||||
}
|
||||
}
|
||||
for (int i = 0;i < bindings.length; i++) {
|
||||
if (bindings[i] instanceof ICPPNamespace) {
|
||||
filtered.add(bindings[i]);
|
||||
}
|
||||
}
|
||||
|
||||
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()]);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
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.DOMException;
|
||||
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.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;
|
||||
|
@ -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.index.IIndex;
|
||||
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.CharArrayObjectMap;
|
||||
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.index.IIndexScope;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
|
@ -159,6 +161,7 @@ public class CPPSemantics {
|
|||
public boolean forceQualified = false;
|
||||
public boolean forUserDefinedConversion = false;
|
||||
public boolean forAssociatedScopes = false;
|
||||
public boolean contentAssist = false;
|
||||
public boolean prefixLookup = false;
|
||||
public boolean typesOnly = false;
|
||||
public boolean considerConstructors = false;
|
||||
|
@ -926,7 +929,7 @@ public class CPPSemantics {
|
|||
return new CPPScope.CPPScopeProblem( name, IProblemBinding.SEMANTIC_BAD_SCOPE, name.toCharArray() );
|
||||
}
|
||||
private static void mergeResults( LookupData data, Object results, boolean scoped ){
|
||||
if( !data.prefixLookup ){
|
||||
if( !data.contentAssist ){
|
||||
if( results instanceof IBinding ){
|
||||
data.foundItems = ArrayUtil.append( Object.class, (Object[]) data.foundItems, results );
|
||||
} else if( results instanceof Object[] ){
|
||||
|
@ -1015,53 +1018,70 @@ public class CPPSemantics {
|
|||
|
||||
ArrayWrapper directives = null;
|
||||
if( !data.usingDirectivesOnly ){
|
||||
if( ASTInternal.isFullyCached(scope) && !data.prefixLookup && data.astName != null ){
|
||||
IBinding binding = data.prefixLookup ? null : scope.getBinding( data.astName, true );
|
||||
if( ASTInternal.isFullyCached(scope) && !data.contentAssist && data.astName != null ){
|
||||
IBinding binding = data.contentAssist ? null : scope.getBinding( data.astName, true );
|
||||
if( binding != null &&
|
||||
( CPPSemantics.declaredBefore( binding, data.astName ) ||
|
||||
(scope instanceof ICPPClassScope && data.checkWholeClassScope) ) )
|
||||
{
|
||||
mergeResults( data, binding, true );
|
||||
}
|
||||
} else {
|
||||
IBinding b= null;
|
||||
if (!data.prefixLookup && data.astName != null ) {
|
||||
} else if (data.astName != null) {
|
||||
boolean useASTResults = true;
|
||||
IBinding b = null;
|
||||
if (!data.contentAssist) {
|
||||
b= scope.getBinding( data.astName, false );
|
||||
if (b instanceof CPPImplicitFunction || b instanceof CPPImplicitTypedef)
|
||||
mergeResults( data, b, true );
|
||||
} else if (data.prefixLookup && data.astName != null) {
|
||||
} else {
|
||||
IASTNode parent = ASTInternal.getPhysicalNodeOfScope(scope);
|
||||
if (parent == null && scope instanceof IIndexScope) {
|
||||
if (parent == null) {
|
||||
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;
|
||||
useASTResults = false;
|
||||
} else {
|
||||
IIndex index = parent.getTranslationUnit().getIndex();
|
||||
if (index != null) {
|
||||
try {
|
||||
IIndexBinding binding = index.findBinding(ns.getScopeName());
|
||||
if (binding instanceof ICPPNamespace) {
|
||||
ICPPNamespaceScope indexNs = ((ICPPNamespace)binding).getNamespaceScope();
|
||||
IBinding[] bindings = indexNs.find(data.astName.toString(), data.prefixLookup);
|
||||
if (parent instanceof IASTTranslationUnit) {
|
||||
try {
|
||||
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) {
|
||||
ICPPNamespaceScope indexNs = ((ICPPNamespace)binding).getNamespaceScope();
|
||||
IBinding[] bindings = indexNs.find(data.astName.toString(), data.prefixLookup);
|
||||
mergeResults(data, bindings, true);
|
||||
useASTResults = false;
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
IASTName[] inScope = lookupInScope( data, scope, blockItem );
|
||||
if (inScope != null) {
|
||||
mergeResults( data, inScope, 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);
|
||||
}
|
||||
|
||||
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) {
|
||||
mergeResults( data, inScope, true );
|
||||
} else if (b instanceof IIndexBinding) {
|
||||
mergeResults( data, b, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( (!data.hasResults() || data.prefixLookup) && scope instanceof ICPPNamespaceScope ){
|
||||
if( (!data.hasResults() || data.contentAssist) && scope instanceof ICPPNamespaceScope ){
|
||||
directives = new ArrayWrapper();
|
||||
directives.array = ((ICPPNamespaceScope) scope).getUsingDirectives();
|
||||
if( directives.array != null ){
|
||||
|
@ -1077,7 +1097,7 @@ public class CPPSemantics {
|
|||
|
||||
if( !data.ignoreUsingDirectives ) {
|
||||
data.visited.clear();
|
||||
if( data.prefixLookup || !data.hasResults() ){
|
||||
if( data.contentAssist || !data.hasResults() ){
|
||||
Object[] transitives = lookupInNominated( data, scope, null );
|
||||
|
||||
processDirectives( data, scope, transitives );
|
||||
|
@ -1087,14 +1107,14 @@ public class CPPSemantics {
|
|||
while( !data.usingDirectives.isEmpty() && data.usingDirectives.get( scope ) != null ){
|
||||
transitives = lookupInNominated( data, scope, transitives );
|
||||
|
||||
if( !data.qualified() || ( data.prefixLookup || !data.hasResults()) ){
|
||||
if( !data.qualified() || ( data.contentAssist || !data.hasResults()) ){
|
||||
processDirectives( data, scope, transitives );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( (!data.prefixLookup && (data.problem != null || data.hasResults())) ||
|
||||
if( (!data.contentAssist && (data.problem != null || data.hasResults())) ||
|
||||
( friendInLocalClass && !(scope instanceof ICPPClassScope) ) )
|
||||
{
|
||||
return;
|
||||
|
@ -1104,7 +1124,7 @@ public class CPPSemantics {
|
|||
mergeResults( data, lookupInParents( data, scope ), true );
|
||||
}
|
||||
|
||||
if( !data.prefixLookup && (data.problem != null || data.hasResults()) )
|
||||
if( !data.contentAssist && (data.problem != null || data.hasResults()) )
|
||||
return;
|
||||
|
||||
//if still not found, loop and check our containing scope
|
||||
|
@ -1192,12 +1212,15 @@ public class CPPSemantics {
|
|||
//is circular inheritance
|
||||
if( ! data.inheritanceChain.containsKey( parent ) ){
|
||||
//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 );
|
||||
else
|
||||
else if (ASTInternal.getPhysicalNodeOfScope(lookIn) != null
|
||||
&& ASTInternal.getPhysicalNodeOfScope(parent) == null)
|
||||
inherited = parent.find(data.astName.toString(), data.prefixLookup);
|
||||
else
|
||||
inherited = lookupInScope( data, parent, null );
|
||||
|
||||
if( inherited == null || data.prefixLookup ){
|
||||
if( inherited == null || data.contentAssist ){
|
||||
Object temp = lookupInParents( data, parent );
|
||||
if( inherited != null ){
|
||||
inherited = mergePrefixResults( null, inherited, true );
|
||||
|
@ -1218,7 +1241,7 @@ public class CPPSemantics {
|
|||
if( result == null ){
|
||||
result = inherited;
|
||||
} else if ( inherited != null ) {
|
||||
if( !data.prefixLookup ) {
|
||||
if( !data.contentAssist ) {
|
||||
if( result instanceof Object [] ){
|
||||
Object [] r = (Object[]) result;
|
||||
for( int j = 0; j < r.length && r[j] != null; j++ ) {
|
||||
|
@ -1582,7 +1605,7 @@ public class CPPSemantics {
|
|||
ArrayWrapper usings = new ArrayWrapper();
|
||||
|
||||
boolean found = false;
|
||||
if( ASTInternal.isFullyCached(temp) && !data.prefixLookup ){
|
||||
if( ASTInternal.isFullyCached(temp) && !data.contentAssist ){
|
||||
IBinding binding = temp.getBinding( data.astName, true );
|
||||
if( binding != null &&
|
||||
( CPPSemantics.declaredBefore( binding, data.astName ) ||
|
||||
|
@ -1591,6 +1614,12 @@ public class CPPSemantics {
|
|||
mergeResults( data, binding, 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 {
|
||||
IASTName [] f = lookupInScope( data, temp, null );
|
||||
if( f != null ) {
|
||||
|
@ -1928,7 +1957,7 @@ public class CPPSemantics {
|
|||
}
|
||||
|
||||
static private IBinding resolveAmbiguities( CPPSemantics.LookupData data, IASTName name ) throws DOMException {
|
||||
if( !data.hasResults() || data.prefixLookup )
|
||||
if( !data.hasResults() || data.contentAssist )
|
||||
return null;
|
||||
|
||||
IBinding type = null;
|
||||
|
@ -3280,61 +3309,38 @@ public class CPPSemantics {
|
|||
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, 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;
|
||||
|
||||
try {
|
||||
lookup( data, scope );
|
||||
} catch (DOMException e) {
|
||||
return new IBinding [] { e.getProblem() };
|
||||
if (prefixLookup) {
|
||||
LookupData data = createLookupData( astName, true );
|
||||
data.contentAssist = true;
|
||||
data.prefixLookup = true;
|
||||
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);
|
||||
}
|
||||
|
||||
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[] 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);
|
||||
}
|
||||
|
||||
public static IBinding [] prefixLookup( IASTName name, Object start ){
|
||||
LookupData data = createLookupData( name, true );
|
||||
data.prefixLookup = true;
|
||||
data.foundItems = new CharArrayObjectMap( 2 );
|
||||
|
||||
|
||||
private static IBinding [] contentAssistLookup( LookupData data, Object start ){
|
||||
try {
|
||||
lookup( data, start );
|
||||
} catch ( DOMException e ) {
|
||||
|
@ -3373,6 +3379,43 @@ public class CPPSemantics {
|
|||
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) {
|
||||
IASTName name = declarator.getName();
|
||||
ICPPASTTemplateDeclaration templateDecl = CPPTemplates.getTemplateDeclaration( name );
|
||||
|
|
|
@ -193,6 +193,9 @@ ICPPClassScope, IPDOMMemberOwner, IIndexType, IIndexScope {
|
|||
return;
|
||||
visited.add(this);
|
||||
|
||||
// Class is in its own scope
|
||||
visitor.visit(this);
|
||||
|
||||
// Get my members
|
||||
accept(visitor);
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@ public class CompletionTest_ClassReference_NoPrefix extends CompletionProposals
|
|||
private final String[] expectedResults = {
|
||||
"aClass",
|
||||
"anotherClass",
|
||||
"ClassA",
|
||||
"xOtherClass"
|
||||
};
|
||||
|
||||
|
|
|
@ -308,6 +308,22 @@ public class CompletionTests extends AbstractContentAssistTest {
|
|||
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*/
|
||||
public void testEnums_GlobalScope() throws Exception {
|
||||
final String[] expected= {
|
||||
|
@ -585,4 +601,12 @@ public class CompletionTests extends AbstractContentAssistTest {
|
|||
};
|
||||
assertCompletionResults(fCursorOffset, expected, true);
|
||||
}
|
||||
|
||||
//using namespace ns;void gfunc(){NSC/*cursor*/
|
||||
public void testUsingDirective() throws Exception {
|
||||
final String[] expected= {
|
||||
"NSCONST"
|
||||
};
|
||||
assertCompletionResults(fCursorOffset, expected, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ public class ParameterHintTests extends AbstractContentAssistTest {
|
|||
////TODO move function into header once indexer supports templates
|
||||
//template<class T>void tFunc(T x, T y);
|
||||
//void foo(){tFunc(
|
||||
public void testTemplateFunction() throws Exception {
|
||||
public void _testTemplateFunction() throws Exception {
|
||||
assertParameterHints(new String[] {
|
||||
"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 {
|
||||
assertParameterHints(new String[] {
|
||||
"pi(aClass a) int"
|
||||
|
|
|
@ -117,19 +117,22 @@ public class CContentAssistInvocationContext extends ContentAssistInvocationCont
|
|||
if (proj == null) return null;
|
||||
|
||||
try{
|
||||
fIndex = CCorePlugin.getIndexManager().getIndex(proj,
|
||||
IIndexManager.ADD_DEPENDENCIES | IIndexManager.ADD_DEPENDENT);
|
||||
|
||||
try {
|
||||
fIndex.acquireReadLock();
|
||||
} catch (InterruptedException e) {
|
||||
fIndex = null;
|
||||
}
|
||||
|
||||
IPDOMManager manager = CCorePlugin.getPDOMManager();
|
||||
String indexerId = manager.getIndexerId(proj);
|
||||
|
||||
if (!IPDOMManager.ID_NO_INDEXER.equals(indexerId)) {
|
||||
fIndex = CCorePlugin.getIndexManager().getIndex(proj,
|
||||
IIndexManager.ADD_DEPENDENCIES | IIndexManager.ADD_DEPENDENT);
|
||||
|
||||
try {
|
||||
fIndex.acquireReadLock();
|
||||
} catch (InterruptedException e) {
|
||||
fIndex = null;
|
||||
}
|
||||
}
|
||||
|
||||
int flags = ITranslationUnit.AST_SKIP_ALL_HEADERS;
|
||||
if (fIndex == null || IPDOMManager.ID_NO_INDEXER.equals(indexerId)) {
|
||||
if (fIndex == null) {
|
||||
flags = 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue