1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 09:25:31 +02:00

Filtering by visibility for content assist. Bug 172305.

This commit is contained in:
Sergey Prigogin 2009-10-06 14:50:28 +00:00
parent 164d59a0d8
commit 4795e461e7
15 changed files with 496 additions and 266 deletions

View file

@ -689,13 +689,29 @@ public class ASTTypeUtil {
return false;
}
}
/**
* Checks if a type is present in an array of types.
* @param type a type.
* @param array an array of types
* @return offset of the first occurrence of type in the array, or -1 if not found.
* @since 5.2
*/
public static int findType(IType type, IType[] array) {
for (int i = 0; i < array.length; i++) {
if (type.isSameType(array[i])) {
return i;
}
}
return -1;
}
private static String[] getQualifiedNameForAnonymous(ICPPBinding binding, boolean normalize) throws DOMException {
LinkedList<String> result= new LinkedList<String>();
result.addFirst(getNameForAnonymous(binding));
IBinding owner= binding.getOwner();
while(owner instanceof ICPPNamespace || owner instanceof IType) {
while (owner instanceof ICPPNamespace || owner instanceof IType) {
char[] name= owner.getNameCharArray();
if (name == null || name.length == 0) {
if (!(binding instanceof ICPPNamespace)) {
@ -760,7 +776,6 @@ public class ASTTypeUtil {
return null;
}
private static int findFileNameStart(char[] fname) {
for (int i= fname.length - 2; i >= 0; i--) {
switch (fname[i]) {

View file

@ -9,6 +9,7 @@
* Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems)
* Bryan Wilkinson (QNX)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;

View file

@ -1645,7 +1645,7 @@ public class CVisitor extends ASTQueries {
* Searches for the function enclosing the given node. May return <code>null</code>.
*/
public static IBinding findEnclosingFunction(IASTNode node) {
while(node != null && node instanceof IASTFunctionDefinition == false) {
while (node != null && !(node instanceof IASTFunctionDefinition)) {
node= node.getParent();
}
if (node == null)

View file

@ -49,6 +49,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
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.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
@ -64,6 +66,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassType.CPPClassTypeProblem;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.core.runtime.CoreException;
/**
@ -121,6 +124,41 @@ public class ClassTypeHelper {
return resultSet.keyArray(IBinding.class);
}
/**
* Checks if a binding is a friend of a class. Only classes and functions can be friends of a class.
* A class is considered a friend of itself.
* @param binding a binding.
* @param classType a class.
* @return <code>true</code> if <code>binding</code> is a friend of <code>classType</code>.
* @throws DOMException
*/
public static boolean isFriend(IBinding binding, ICPPClassType classType) throws DOMException {
IType type;
if (binding instanceof ICPPClassType) {
type = (IType) binding;
if (type.isSameType(classType)) {
return true;
}
for (IBinding friend : classType.getFriends()) {
if (friend instanceof ICPPClassType && type.isSameType((IType) friend)) {
return true;
}
}
} else if (binding instanceof ICPPFunction) {
type = ((ICPPFunction) binding).getType();
char[] name = binding.getNameCharArray();
for (IBinding friend : classType.getFriends()) {
if (friend instanceof ICPPFunction &&
CharArrayUtils.equals(name, friend.getNameCharArray()) &&
SemanticUtil.isSameOwner(binding.getOwner(), friend.getOwner()) &&
type.isSameType(((ICPPFunction) friend).getType())) {
return true;
}
}
}
return false;
}
/**
* A host maybe backed up with a definition from the index.
* @throws DOMException
@ -206,22 +244,39 @@ public class ClassTypeHelper {
return (ICPPField[]) ArrayUtil.trim(ICPPField.class, result);
}
public static ICPPClassType[] getAllBases(ICPPClassType ct) throws DOMException {
public static ICPPClassType[] getAllBases(ICPPClassType classType) throws DOMException {
return getAllBases(classType, ICPPBase.v_private);
}
/**
* Returns all direct and indirect base classes that have at least a given visibility level.
* @param classType a class
* @param minVisibility one of <code>ICPPBase.v_private</code>, <code>ICPPBase.v_protected</code>,
* or <code>ICPPBase.v_public</code>. All base classes are returned if
* <code>minVisibility == ICPPBase.v_private</code> since it is the lowest visibility level.
* @return An array of visible base classes in arbitrary order.
* @throws DOMException
*/
public static ICPPClassType[] getAllBases(ICPPClassType classType, int minVisibility) throws DOMException {
HashSet<ICPPClassType> result= new HashSet<ICPPClassType>();
result.add(ct);
getAllBases(ct, result);
result.remove(ct);
result.add(classType);
getAllBases(classType, minVisibility, result);
result.remove(classType);
return result.toArray(new ICPPClassType[result.size()]);
}
private static void getAllBases(ICPPClassType ct, HashSet<ICPPClassType> result) throws DOMException {
ICPPBase[] bases= ct.getBases();
private static void getAllBases(ICPPClassType classType, int minVisibility, HashSet<ICPPClassType> result) throws DOMException {
ICPPBase[] bases= classType.getBases();
for (ICPPBase base : bases) {
IBinding b= base.getBaseClass();
if (b instanceof ICPPClassType) {
final ICPPClassType ctbase = (ICPPClassType) b;
if (result.add(ctbase)) {
getAllBases(ctbase, result);
// Note that numeric visibility values are ordered backwards:
// ICPPBase.v_public < ICPPBase.v_protected < ICPPBase.v_private.
if (base.getVisibility() <= minVisibility) {
IBinding b= base.getBaseClass();
if (b instanceof ICPPClassType) {
final ICPPClassType baseClass = (ICPPClassType) b;
if (result.add(baseClass)) {
getAllBases(baseClass, minVisibility, result);
}
}
}
}
@ -229,7 +284,7 @@ public class ClassTypeHelper {
public static ICPPMethod[] getAllDeclaredMethods(ICPPClassType ct) throws DOMException {
ICPPMethod[] methods= ct.getDeclaredMethods();
ICPPClassType[] bases= getAllBases(ct);
ICPPClassType[] bases= getAllBases(ct, ICPPBase.v_private);
for (ICPPClassType base : bases) {
methods = (ICPPMethod[]) ArrayUtil.addAll(ICPPMethod.class, methods, base.getDeclaredMethods());
}
@ -242,7 +297,7 @@ public class ClassTypeHelper {
ICPPClassScope scope= (ICPPClassScope) ct.getCompositeScope();
set.addAll(scope.getImplicitMethods());
ICPPClassType[] bases= getAllBases(ct);
ICPPClassType[] bases= getAllBases(ct, ICPPBase.v_private);
for (ICPPClassType base : bases) {
set.addAll(base.getDeclaredMethods());
final IScope compositeScope = base.getCompositeScope();
@ -363,7 +418,7 @@ public class ClassTypeHelper {
public static IField[] getFields(ICPPClassType ct) throws DOMException {
IField[] fields = ct.getDeclaredFields();
ICPPClassType[] bases = getAllBases(ct);
ICPPClassType[] bases = getAllBases(ct, ICPPBase.v_private);
for (ICPPClassType base : bases) {
fields = (IField[]) ArrayUtil.addAll(IField.class, fields, base.getFields());
}
@ -431,7 +486,7 @@ public class ClassTypeHelper {
if (sourceClass == null || targetClass == null)
return false;
ICPPClassType[] bases= getAllBases(sourceClass);
ICPPClassType[] bases= getAllBases(sourceClass, ICPPBase.v_private);
for (ICPPClassType base : bases) {
if (base.isSameType(targetClass))
return true;
@ -601,7 +656,7 @@ public class ClassTypeHelper {
return null;
List<IType> inheritedTypeids = new ArrayList<IType>();
ICPPClassType[] bases= getAllBases(owner);
ICPPClassType[] bases= getAllBases(owner, ICPPBase.v_private);
for (ICPPClassType base : bases) {
if (!(base instanceof ICPPDeferredClassInstance)) {
ICPPMethod baseMethod= getMethodInClass(base, kind);
@ -693,4 +748,54 @@ public class ClassTypeHelper {
}
return null;
}
/**
* Compares two visibility values. ICPPBase.v_public is the highest visibility, ICPPBase.v_private is
* the lowest.
* @param visibility1 one of: ICPPBase.v_public, ICPPBase.v_protected, ICPPBase.v_private.
* @param visibility2 one of: ICPPBase.v_public, ICPPBase.v_protected, ICPPBase.v_private.
* @return <code>true</code> if <code>visibility1</code> is less than <code>visibility2</code>.
*/
public static boolean isLessVisibility(int visibility1, int visibility2) {
// Note that numeric visibility values are ordered backwards:
// ICPPBase.v_public < ICPPBase.v_protected < ICPPBase.v_private.
return visibility1 > visibility2;
}
/**
* Removes bindings that are not visible at the given visibility level.
* @param bindings bindings to be filtered.
* @param minVisibility one of: ICPPMember.v_public, ICPPMember.v_protected, ICPPMember.v_private.
*/
public static void filterByVisibility(IBinding[] bindings, int minVisibility) {
final int length = bindings.length;
int pos = 0;
for (int i = 0; i < length; i++) {
final IBinding binding= bindings[i];
if (binding != null && isVisible(binding, minVisibility)) {
bindings[pos++]= binding;
}
}
while (pos < length) {
bindings[pos++]= null;
}
}
/**
* Checks if a binding is visible at the given visibility level.
* @param binding a binding.
* @param minVisibility one of: ICPPMember.v_public, ICPPMember.v_protected, ICPPMember.v_private.
* @return <code>true</code> if visibility of the binding is not less than <code>minVisibility</code>.
*/
public static boolean isVisible(IBinding binding, int minVisibility) {
try {
if (binding instanceof ICPPMember) {
return !isLessVisibility(((ICPPMember) binding).getVisibility(), minVisibility);
}
// TODO(sprigogin): Handle visibility of nested types
} catch (DOMException e) {
// Presume visibility if anything goes wrong.
}
return true;
}
}

View file

@ -7,6 +7,7 @@
*
* Contributors:
* Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
@ -30,13 +31,15 @@ import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalUnknownScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
/**
* Helper class for performing the base class lookup. First a directed graph without loops is computed to represent the base
* class hierarchy up to those bases for which the lookup finds matches. Next, from these leaves we search for virtual bases
* that are hidden. With this information the matches are extracted from the graph.
* Helper class for performing the base class lookup. First a directed graph without loops is computed
* to represent the base class hierarchy up to those bases for which the lookup finds matches. Next, from
* these leaves we search for virtual bases that are hidden. With this information the matches are extracted
* from the graph.
*/
class BaseClassLookup {
public static void lookupInBaseClasses(LookupData data, ICPPClassScope classScope, IIndexFileSet fileSet) {
@ -46,9 +49,10 @@ class BaseClassLookup {
final ICPPClassType classType= classScope.getClassType();
if (classType == null)
return;
final HashMap<IScope, BaseClassLookup> infoMap = new HashMap<IScope, BaseClassLookup>();
BaseClassLookup rootInfo= lookupInBaseClass(data, null, false, classType, fileSet, infoMap, 0);
BaseClassLookup rootInfo= lookupInBaseClass(data, null, false, classType, ICPPMember.v_public,
fileSet, infoMap, 0);
if (data.contentAssist) {
rootInfo.collectResultForContentAssist(data);
} else {
@ -71,6 +75,7 @@ class BaseClassLookup {
private BaseClassLookup(ICPPClassType type) {
fClassType= type;
}
ICPPClassType getClassType() {
return fClassType;
}
@ -78,9 +83,11 @@ class BaseClassLookup {
IBinding[] getResult() {
return fBindings;
}
boolean containsVirtualBase() {
return (fVirtual != null && fVirtual.nextSetBit(0) >= 0);
return fVirtual != null && fVirtual.nextSetBit(0) >= 0;
}
boolean hasMatches() {
return fBindings != null && fBindings.length > 0 && fBindings[0] != null;
}
@ -104,11 +111,12 @@ class BaseClassLookup {
public void setHiddenAsVirtualBase() {
fHiddenAsVirtualBase= true;
}
public void propagateHiddenAsVirtual() {
if (fPropagationDone)
return;
fPropagationDone= true;
for (int i=0; i<fChildren.size(); i++) {
for (int i= 0; i < fChildren.size(); i++) {
BaseClassLookup child = fChildren.get(i);
if (fVirtual.get(i)) {
child.setHiddenAsVirtualBase();
@ -133,16 +141,27 @@ class BaseClassLookup {
return false;
}
static BaseClassLookup lookupInBaseClass(LookupData data, ICPPClassScope baseClassScope, boolean isVirtual, ICPPClassType root, IIndexFileSet fileSet, HashMap<IScope, BaseClassLookup> infoMap, int depth) {
static BaseClassLookup lookupInBaseClass(LookupData data, ICPPClassScope baseClassScope,
boolean isVirtual, ICPPClassType root, int minVisibility, IIndexFileSet fileSet,
HashMap<IScope, BaseClassLookup> infoMap, int depth) {
if (depth++ > CPPSemantics.MAX_INHERITANCE_DEPTH)
return null;
if (data.filterByVisibility) {
ICPPClassType classType = baseClassScope != null ? baseClassScope.getClassType() : root;
int baseVisibility = CPPSemantics.getClassVisibility(classType, data.getVisibilityContext());
if (ClassTypeHelper.isLessVisibility(baseVisibility, minVisibility)) {
minVisibility = baseVisibility;
}
}
if (baseClassScope != null) {
BaseClassLookup info= infoMap.get(baseClassScope);
if (info != null) {
// avoid loops
if (info.getResult() == null) {
data.problem = new ProblemBinding(null, IProblemBinding.SEMANTIC_CIRCULAR_INHERITANCE, root.getNameCharArray());
data.problem = new ProblemBinding(null, IProblemBinding.SEMANTIC_CIRCULAR_INHERITANCE,
root.getNameCharArray());
return null;
}
return info;
@ -167,6 +186,10 @@ class BaseClassLookup {
if (data.typesOnly) {
CPPSemantics.removeObjects(members);
}
if (data.filterByVisibility) {
ClassTypeHelper.filterByVisibility(members, minVisibility);
}
if (members != null && members.length > 0 && members[0] != null) {
if (data.prefixLookup) {
matches= members;
@ -180,7 +203,8 @@ class BaseClassLookup {
}
}
// there is no result in the baseClass itself or we do content assist, we have to examine its base-classes
// There is no result in the baseClass itself or we do content assist, we have to examine its
// base-classes
ICPPClassType baseClass= result.getClassType();
if (baseClass != null) {
ICPPBase[] grandBases= null;
@ -194,8 +218,12 @@ class BaseClassLookup {
for (ICPPBase grandBase : grandBases) {
if (grandBase instanceof IProblemBinding)
continue;
try {
if (data.filterByVisibility &&
ClassTypeHelper.isLessVisibility(grandBase.getVisibility(), minVisibility)) {
continue;
}
IBinding grandBaseBinding = grandBase.getBaseClass();
if (!(grandBaseBinding instanceof ICPPClassType)) {
// 14.6.2.3 scope is not examined
@ -219,8 +247,11 @@ class BaseClassLookup {
}
if (!(grandBaseScope instanceof ICPPClassScope))
continue;
BaseClassLookup baseInfo= lookupInBaseClass(data, (ICPPClassScope) grandBaseScope, grandBase.isVirtual(), root, fileSet, infoMap, depth);
BaseClassLookup baseInfo= lookupInBaseClass(data, (ICPPClassScope) grandBaseScope,
grandBase.isVirtual(), root,
minVisibility == ICPPMember.v_private ? ICPPMember.v_protected : minVisibility,
fileSet, infoMap, depth);
if (baseInfo != null)
result.addBase(grandBase.isVirtual(), baseInfo);
} catch (DOMException e) {
@ -296,14 +327,14 @@ class BaseClassLookup {
}
}
}
public void collectResultForContentAssist(LookupData data) {
if (fCollected)
return;
fCollected= true;
data.foundItems = CPPSemantics.mergePrefixResults((CharArrayObjectMap) data.foundItems, fBindings, true);
for (int i=0; i<fChildren.size(); i++) {
BaseClassLookup child = fChildren.get(i);
for (BaseClassLookup child : fChildren) {
child.collectResultForContentAssist(data);
}
}
@ -324,7 +355,7 @@ class BaseClassLookup {
fCollected= true;
result= (IBinding[]) ArrayUtil.addAll(IBinding.class, result, fBindings);
for (int i=0; i<fChildren.size(); i++) {
for (int i= 0; i < fChildren.size(); i++) {
BaseClassLookup child = fChildren.get(i);
result= child.collectResult(data, fVirtual.get(i), result);
}

View file

@ -25,6 +25,7 @@ import java.util.List;
import java.util.Set;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.EScopeKind;
@ -172,6 +173,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUsingDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUsingDirective;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVariable;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPASTInternalScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
@ -813,6 +815,11 @@ public class CPPSemantics {
if (data.typesOnly) {
removeObjects(bindings);
}
if (data.filterByVisibility && scope instanceof ICPPClassScope) {
int visibility = getClassVisibility(((ICPPClassScope) scope).getClassType(),
data.getVisibilityContext());
ClassTypeHelper.filterByVisibility(bindings, visibility);
}
mergeResults(data, bindings, true);
// store using-directives found in this block or namespace for later use.
@ -999,6 +1006,41 @@ public class CPPSemantics {
}
}
/**
* Returns visibility of a class in a given context.
* @param classType a class
* @param visibilityContext @see LookupData.visibilityContext
* @return One of: ICPPMember.v_public, ICPPMember.v_protected, ICPPMember.v_private.
*/
static int getClassVisibility(ICPPClassType classType, IBinding[] visibilityContext) {
int visibility = ICPPMember.v_public;
try {
for (IBinding context : visibilityContext) {
if (ClassTypeHelper.isFriend(context, classType)) {
return ICPPMember.v_private;
}
if (visibility == ICPPMember.v_public && context instanceof ICPPClassType) {
ICPPClassType contextClass = (ICPPClassType) context;
ICPPBase[] bases = contextClass.getBases();
for (ICPPBase base : bases) {
IBinding baseClass = base.getBaseClass();
if (baseClass instanceof ICPPClassType) {
ICPPClassType[] baseClasses =
ClassTypeHelper.getAllBases((ICPPClassType) baseClass, ICPPMember.v_protected);
if (ASTTypeUtil.findType(classType, baseClasses) >= 0) {
visibility = ICPPMember.v_protected;
break;
}
}
}
}
}
} catch (DOMException e) {
visibility = ICPPMember.v_private; // Presume complete visibility if anything goes wrong.
}
return visibility;
}
private static ICPPTemplateScope enclosingTemplateScope(IASTNode node) {
IASTNode parent= node.getParent();
if (parent instanceof IASTName) {
@ -1674,9 +1716,9 @@ public class CPPSemantics {
} else if (type != temp) {
int c = compareByRelevance(data, type, temp);
if (c < 0) {
type= temp;
type= temp;
} else if (c == 0) {
if (((IType)type).isSameType((IType) temp)) {
if (((IType) type).isSameType((IType) temp)) {
if (type instanceof ITypedef && !(temp instanceof ITypedef)) {
// Between same types prefer non-typedef.
type= temp;
@ -1695,7 +1737,7 @@ public class CPPSemantics {
} else {
int c = compareByRelevance(data, obj, temp);
if (c < 0) {
obj= temp;
obj= temp;
} else if (c == 0) {
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP,
data.getFoundBindings());
@ -2829,18 +2871,19 @@ public class CPPSemantics {
LookupData data = createLookupData(name, true);
data.contentAssist = true;
data.prefixLookup = prefixLookup;
data.filterByVisibility = true;
data.foundItems = new CharArrayObjectMap(2);
return contentAssistLookup(data, name);
}
private static IBinding[] contentAssistLookup(LookupData data, Object start) {
private static IBinding[] contentAssistLookup(LookupData data, Object start) {
try {
lookup(data, start);
} catch (DOMException e) {
}
CharArrayObjectMap map = (CharArrayObjectMap) data.foundItems;
IBinding[] result = null;
IBinding[] result = IBinding.EMPTY_BINDING_ARRAY;
if (!map.isEmpty()) {
char[] key = null;
Object obj = null;
@ -2849,28 +2892,28 @@ public class CPPSemantics {
key = map.keyAt(i);
obj = map.get(key);
if (obj instanceof IBinding) {
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, obj);
result = ArrayUtil.append(result, (IBinding) obj);
} else if (obj instanceof IASTName) {
IBinding binding = ((IASTName) obj).resolveBinding();
if (binding != null && !(binding instanceof IProblemBinding))
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, binding);
result = ArrayUtil.append(result, binding);
} else if (obj instanceof Object[]) {
Object[] objs = (Object[]) obj;
for (int j = 0; j < objs.length && objs[j] != null; j++) {
Object item = objs[j];
if (item instanceof IBinding) {
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, item);
result = ArrayUtil.append(result, (IBinding) item);
} else if (item instanceof IASTName) {
IBinding binding = ((IASTName) item).resolveBinding();
if (binding != null && !(binding instanceof IProblemBinding))
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, binding);
result = ArrayUtil.append(result, binding);
}
}
}
}
}
return (IBinding[]) ArrayUtil.trim(IBinding.class, result);
return ArrayUtil.trim(result);
}
private static IBinding[] standardLookup(LookupData data, Object start) {
@ -2933,7 +2976,7 @@ public class CPPSemantics {
return false;
}
static protected IBinding resolveUnknownName(IScope scope, ICPPUnknownBinding unknown) {
protected static IBinding resolveUnknownName(IScope scope, ICPPUnknownBinding unknown) {
final IASTName unknownName = unknown.getUnknownName();
LookupData data = new LookupData(unknownName);
data.checkPointOfDecl= false;

View file

@ -873,8 +873,8 @@ public class CPPVisitor extends ASTQueries {
}
/**
* Searches for an enclosing function definition or declaration, returns
* the name of the function. If you pass the name of a function, it will be returned.
* Returns enclosing function definition, or <code>null</code> if the given node
* is not part of a function definition.
*/
public static ICPPASTFunctionDefinition findEnclosingFunctionDefinition(IASTNode node) {
while (node != null) {
@ -1087,7 +1087,7 @@ public class CPPVisitor extends ASTQueries {
}
return null;
}
public static class CollectProblemsAction extends CPPASTVisitor {
{
shouldVisitDeclarations = true;
@ -1879,8 +1879,10 @@ public class CPPVisitor extends ASTQueries {
break;
if (owner instanceof ICPPFunction)
break;
if (owner instanceof ICPPNamespace && n.length() == 0)
if (owner instanceof ICPPNamespace && n.length() == 0) {
// TODO(sprigogin): Do not ignore anonymous namespaces.
continue;
}
ns = (String[]) ArrayUtil.append(String.class, ns, n);
}
@ -1995,12 +1997,36 @@ public class CPPVisitor extends ASTQueries {
return null;
}
/**
* Searches for the function or class enclosing the given node. May return <code>null</code>.
*/
public static IBinding findEnclosingFunctionOrClass(IASTNode node) {
IASTName name = null;
for (; node != null; node= node.getParent()) {
if (node instanceof IASTFunctionDefinition) {
IASTDeclarator dtor= findInnermostDeclarator(((IASTFunctionDefinition) node).getDeclarator());
if (dtor != null) {
name= dtor.getName();
}
break;
}
if (node instanceof IASTCompositeTypeSpecifier) {
name= ((IASTCompositeTypeSpecifier) node).getName();
break;
}
}
if (name == null)
return null;
return name.resolveBinding();
}
public static IBinding findNameOwner(IASTName name, boolean allowFunction) {
IASTNode node= name;
while (node instanceof IASTName) {
if (node instanceof ICPPASTQualifiedName) {
IASTName[] qn= ((ICPPASTQualifiedName) node).getNames();
int i = qn.length;
int i= qn.length;
while (--i >= 0) {
if (qn[i] == name) {
break;
@ -2010,16 +2036,17 @@ public class CPPVisitor extends ASTQueries {
break;
return qn[i].resolveBinding();
}
name = (IASTName) node;
name= (IASTName) node;
node= node.getParent();
}
return findDeclarationOwner(node, allowFunction);
}
/**
* Searches for the first function, class or namespace enclosing the declaration the provided
* node belongs to and returns the binding for it. Returns <code>null</code>, if the declaration
* is not enclosed by any of the above constructs.
* Searches for the first class, namespace, or function, if <code>allowFunction</code>
* is <code>true</code>, enclosing the declaration the provided node belongs to and returns
* the binding for it. Returns <code>null</code>, if the declaration is not enclosed by any
* of the above constructs.
*/
public static IBinding findDeclarationOwner(IASTNode node, boolean allowFunction) {
// Search for declaration
@ -2033,7 +2060,7 @@ public class CPPVisitor extends ASTQueries {
final IASTNode parent= node.getParent();
if (parent instanceof IASTSimpleDeclaration) {
final IASTSimpleDeclaration sdecl = (IASTSimpleDeclaration) parent;
if (sdecl.getDeclarators().length==0) {
if (sdecl.getDeclarators().length == 0) {
isNonSimpleElabDecl= false;
}
}

View file

@ -18,6 +18,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
@ -41,6 +42,7 @@ import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.c.ICASTFieldDesignator;
@ -64,6 +66,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
@ -83,12 +86,9 @@ public class LookupData {
protected CPPASTTranslationUnit tu;
public Map<ICPPNamespaceScope, List<ICPPNamespaceScope>> usingDirectives= Collections.emptyMap();
/*
* Used to ensure we don't visit things more than once
*/
/** Used to ensure we don't visit things more than once. */
public ObjectSet<IScope> visited= new ObjectSet<IScope>(1);
@SuppressWarnings("unchecked")
public ObjectSet<IScope> associated = ObjectSet.EMPTY_SET;
@ -99,17 +99,23 @@ public class LookupData {
public boolean forAssociatedScopes = false;
public boolean contentAssist = false;
public boolean prefixLookup = false;
/** Don't return private/protected members that are not visible. */
public boolean filterByVisibility = false;
public boolean typesOnly = false;
public boolean considerConstructors = false;
public boolean checkPointOfDecl= true; // for lookup of unknown bindings the point of declaration can be reversed.
public boolean usesEnclosingScope= true; // for field references or qualified names, enclosing template declarations are ignored.
public boolean firstArgIsImpliedMethodArg = false; // when computing the cost of a method call treat the first argument as the implied method argument
/** For lookup of unknown bindings the point of declaration can be reversed. */
public boolean checkPointOfDecl= true;
/** For field references or qualified names, enclosing template declarations are ignored. */
public boolean usesEnclosingScope= true;
/** When computing the cost of a method call, treat the first argument as the implied method argument. */
public boolean firstArgIsImpliedMethodArg = false;
public boolean ignoreMembers = false;
public ICPPClassType skippedScope;
public Object foundItems = null;
private Object[] functionArgs;
private IType[] functionArgTypes;
private IBinding[] visibilityContext;
public ProblemBinding problem;
public LookupData(IASTName n) {
@ -658,4 +664,39 @@ public class LookupData {
}
return IBinding.EMPTY_BINDING_ARRAY;
}
/**
* Visibility context is a class or/and a function that determine visibility of private/protected
* members by participating in friendship or class inheritance relationships. If both, a class and
* a function are present in the context, the class has to be local to the function.
*/
public IBinding[] getVisibilityContext() {
if (visibilityContext == null) {
visibilityContext = IBinding.EMPTY_BINDING_ARRAY;
try {
IBinding previous = null;
for (IBinding binding = CPPVisitor.findEnclosingFunctionOrClass(astName);
binding != null; binding = binding.getOwner()) {
if (binding instanceof ICPPMethod ||
// Definition of an undeclared method.
binding instanceof IProblemBinding &&
((IProblemBinding) binding).getID() == IProblemBinding.SEMANTIC_MEMBER_DECLARATION_NOT_FOUND) {
continue;
}
if (binding instanceof ICPPClassType && previous instanceof ICPPClassType) {
// Only the innermost class participates in the visibility context.
continue;
}
if (binding instanceof ICPPFunction || binding instanceof ICPPClassType) {
visibilityContext = ArrayUtil.append(visibilityContext, binding);
previous = binding;
}
}
} catch (DOMException e) {
CCorePlugin.log(e);
}
visibilityContext = ArrayUtil.trim(visibilityContext);
}
return visibilityContext;
}
}

View file

@ -13,6 +13,7 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBinding;
@ -26,6 +27,7 @@ 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.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
@ -289,7 +291,6 @@ public class SemanticUtil {
return type;
}
public static IType[] getSimplifiedTypes(IType[] types) {
// Don't create a new array until it's really needed.
IType[] result = types;
@ -392,4 +393,38 @@ public class SemanticUtil {
}
return baseType;
}
/**
* Returns <code>true</code> if two bindings have the same owner.
*/
public static boolean isSameOwner(IBinding owner1, IBinding owner2) {
try {
// Ignore anonymous namespaces
while (owner1 instanceof ICPPNamespace && owner1.getNameCharArray().length == 0)
owner1= owner1.getOwner();
// Ignore anonymous namespaces
while (owner2 instanceof ICPPNamespace && owner2.getNameCharArray().length == 0)
owner2= owner2.getOwner();
if (owner1 == null)
return owner2 == null;
if (owner2 == null)
return false;
if (owner1 instanceof IType) {
if (owner2 instanceof IType) {
return ((IType) owner1).isSameType((IType) owner2);
}
} else if (owner1 instanceof ICPPNamespace) {
if (owner2 instanceof ICPPNamespace) {
if (!CharArrayUtils.equals(owner1.getNameCharArray(), owner2.getNameCharArray()))
return false;
return isSameOwner(owner1.getOwner(), owner2.getOwner());
}
}
} catch (DOMException e) {
CCorePlugin.log(e);
}
return false;
}
}

View file

@ -17,12 +17,8 @@ import java.util.List;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
@ -31,7 +27,7 @@ import org.eclipse.core.runtime.CoreException;
/**
* Mirrors type-hierarchy from DOM interfaces
*/
abstract class PDOMCPPBinding extends PDOMBinding implements ICPPBinding {
public abstract class PDOMCPPBinding extends PDOMBinding implements ICPPBinding {
@SuppressWarnings("hiding")
protected static final int RECORD_SIZE= PDOMBinding.RECORD_SIZE + 0;
@ -39,44 +35,11 @@ abstract class PDOMCPPBinding extends PDOMBinding implements ICPPBinding {
public PDOMCPPBinding(PDOMLinkage linkage, long record) {
super(linkage, record);
}
public PDOMCPPBinding(PDOMLinkage linkage, PDOMNode parent, char[] name) throws CoreException {
super(linkage, parent, name);
}
protected boolean isSameOwner(IBinding owner1, IBinding owner2) {
try {
// ignore unnamed namespaces
while(owner1 instanceof ICPPNamespace && owner1.getNameCharArray().length == 0)
owner1= owner1.getOwner();
// ignore unnamed namespaces
while(owner2 instanceof ICPPNamespace && owner2.getNameCharArray().length == 0)
owner2= owner2.getOwner();
if (owner1 == null)
return owner2 == null;
if (owner2 == null)
return false;
if (owner1 instanceof IType) {
if (owner2 instanceof IType) {
return ((IType) owner1).isSameType((IType) owner2);
}
return false;
}
if (owner1 instanceof ICPPNamespace) {
if (owner2 instanceof ICPPNamespace) {
if (!CharArrayUtils.equals(owner1.getNameCharArray(), owner2.getNameCharArray()))
return false;
return isSameOwner(owner1.getOwner(), owner2.getOwner());
}
return false;
}
} catch (DOMException e) {
CCorePlugin.log(e);
}
return false;
}
final public char[][] getQualifiedNameCharArray() throws DOMException {
List<char[]> result = new ArrayList<char[]>();
try {

View file

@ -37,6 +37,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
import org.eclipse.cdt.internal.core.pdom.db.Database;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
@ -260,7 +261,7 @@ public class PDOMCPPClassTemplate extends PDOMCPPClassType
if (nchars == null || !CharArrayUtils.equals(nchars, getNameCharArray()))
return false;
return isSameOwner(getOwner(), ctype.getOwner());
return SemanticUtil.isSameOwner(getOwner(), ctype.getOwner());
} catch (DOMException e) {
return false;
}

View file

@ -36,6 +36,7 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.Util;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
import org.eclipse.cdt.internal.core.pdom.db.PDOMNodeLinkedList;
import org.eclipse.cdt.internal.core.pdom.dom.IPDOMMemberOwner;
@ -268,7 +269,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDO
if (nchars == null || !CharArrayUtils.equals(nchars, getNameCharArray()))
return false;
return isSameOwner(getOwner(), ctype.getOwner());
return SemanticUtil.isSameOwner(getOwner(), ctype.getOwner());
} catch (DOMException e) {
CCorePlugin.log(e);
}

View file

@ -22,6 +22,7 @@ import org.eclipse.cdt.core.dom.ast.IEnumerator;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
import org.eclipse.cdt.internal.core.index.IIndexType;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
@ -118,7 +119,7 @@ class PDOMCPPEnumeration extends PDOMCPPBinding implements IEnumeration, IIndexT
if (nchars == null || !CharArrayUtils.equals(nchars, getNameCharArray()))
return false;
return isSameOwner(getOwner(), etype.getOwner());
return SemanticUtil.isSameOwner(getOwner(), etype.getOwner());
}
} catch (DOMException e) {
CCorePlugin.log(e);

View file

@ -14,7 +14,7 @@ import junit.framework.Test;
import junit.framework.TestSuite;
/**
* Test that anonymous types are not returned as possibilites
* Test that anonymous types are not returned as possibilities.
*/
public class CompletionTest_AnonymousTypes extends CompletionProposalsBaseTest{
private final String fileName = "CompletionTestStart40.cpp";

View file

@ -10,6 +10,7 @@
* Bryan Wilkinson (QNX)
* Markus Schorn (Wind River Systems)
* IBM Corporation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.ui.tests.text.contentassist2;
@ -35,7 +36,6 @@ import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
* @since 4.0
*/
public class CompletionTests extends AbstractContentAssistTest {
private static final String HEADER_FILE_NAME = "CompletionTest.h";
private static final String SOURCE_FILE_NAME = "CompletionTest.cpp";
private static final String CURSOR_LOCATION_TAG = "/*cursor*/";
@ -86,6 +86,8 @@ public class CompletionTests extends AbstractContentAssistTest {
// C1* m12();
// C1* m13();
//
//protected:
// void m1protected();
//private:
// void m1private();
//};
@ -102,8 +104,12 @@ public class CompletionTests extends AbstractContentAssistTest {
// C2* m23();
// C1* operator()(int x);
//
//protected:
// void m2protected();
//private:
// void m2private();
// friend void _friend_function(C3* x);
// friend class _friend_class;
//};
//typedef C2 T2;
//
@ -117,6 +123,8 @@ public class CompletionTests extends AbstractContentAssistTest {
// C3* m13();
//
// template<typename T> T tConvert();
//protected:
// void m3protected();
//private:
// void m3private();
//};
@ -215,87 +223,67 @@ public class CompletionTests extends AbstractContentAssistTest {
}
//void gfunc() {C1 v; v.m/*cursor*/
public void _testLocalVariable() throws Exception {
// fails because of additional m1private(void)
// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=172305
public void testLocalVariable() throws Exception {
final String[] expected= {
"m123(void)", "m12(void)", "m13(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void gfunc() {C1 v; v.fMySelf.m/*cursor*/
public void _testLocalVariable_MemberVariable() throws Exception {
// fails because of additional m1private(void)
// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=172305
//void gfunc() {C1 v; v.fMySelf->m/*cursor*/
public void testLocalVariable_MemberVariable() throws Exception {
final String[] expected= {
"m123(void)", "m12(void)", "m13(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void gfunc() {C1 v; v.m12().m/*cursor*/
public void _testLocalVariable_MemberFunction() throws Exception {
// fails because of additional m1private(void)
// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=172305
//void gfunc() {C1 v; v.m12()->m/*cursor*/
public void testLocalVariable_MemberFunction() throws Exception {
final String[] expected= {
"m123(void)", "m12(void)", "m13(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void gfunc() {gfC1().m/*cursor*/
public void _testGlobalFunction() throws Exception {
// fails because of additional m1private(void)
// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=172305
//void gfunc() {gfC1()->m/*cursor*/
public void testGlobalFunction() throws Exception {
final String[] expected= {
"m123(void)", "m12(void)", "m13(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void C1::self() {m/*cursor*/
public void testOwnMember() throws Exception {
final String[] expected= {
"m123(void)", "m12(void)", "m13(void)", "m1private(void)"
"m123(void)", "m12(void)", "m13(void)", "m1private(void)", "m1protected(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void C1::self() {this->m/*cursor*/
public void testOwnMemberViaThis() throws Exception {
final String[] expected= {
"m123(void)", "m12(void)", "m13(void)", "m1private(void)"
"m123(void)", "m12(void)", "m13(void)", "m1private(void)", "m1protected(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void gfunc() {try{int bla;}catch(C1 v) {v.fMySelf.m/*cursor*/
public void _testCatchBlock1() throws Exception {
// fails because of additional m1private(void)
// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=172305
//void gfunc() {try{int bla;}catch(C1 v) {v.fMySelf->m/*cursor*/
public void testCatchBlock1() throws Exception {
final String[] expected= {
"m123(void)", "m12(void)", "m13(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void gfunc() {try{int bla;}catch(C2 c){} catch(C1 v) {v.fMySelf.m/*cursor*/
public void _testCatchBlock2() throws Exception {
// fails because of additional m1private(void)
// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=172305
//void gfunc() {try{int bla;}catch(C2 c){} catch(C1 v) {v.fMySelf->m/*cursor*/
public void testCatchBlock2() throws Exception {
final String[] expected= {
"m123(void)", "m12(void)", "m13(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {gC/*cursor*/
@ -303,8 +291,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"gC1", "gC2"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void C1::f() {gC/*cursor*/
@ -312,8 +299,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"gC1", "gC2"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {C2* cLocal1; while(true) {C1* cLocal2; cL/*cursor*/
@ -321,8 +307,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"cLocal1", "cLocal2"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void C2::f() {C2* cLocal1; while(true) {C1* cLocal2; cL/*cursor*/
@ -330,8 +315,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"cLocal1", "cLocal2"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {C2* cLocal1; cLocal1->f/*cursor*/
@ -339,8 +323,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"fMySelf"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void C2::f() {while(true) {f/*cursor*/
@ -348,8 +331,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"fMySelf"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {gf/*cursor*/
@ -357,8 +339,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"gfC1(void)", "gfC2(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void C3::f() {gf/*cursor*/
@ -366,30 +347,24 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"gfC1(void)", "gfC2(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {C1* l1; l1.m/*cursor*/
public void _testMethods_GlobalScope() throws Exception {
// fails because of additional m1private(void)
// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=172305
//void f() {C1* l1; l1->m/*cursor*/
public void testMethods_GlobalScope() throws Exception {
final String[] expected= {
"m123(void)", "m12(void)", "m13(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void C3::f() {m/*cursor*/
public void _testMethods_MethodScope() throws Exception {
// fails because of additional m1private(void)
// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=172305
public void testMethods_MethodScope() throws Exception {
final String[] expected= {
"m123(void)", "m12(void)", "m13(void)"
"m123(void)", "m12(void)", "m13(void)", "m23(void)", "m1protected(void)",
"m2protected(void)", "m3private(void)", "m3protected(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {C/*cursor*/
@ -397,17 +372,49 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"C1", "C2", "C3"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//class _friend_class { C3* x; void m() {x->m/*cursor*/
public void testTypes_FriendClass() throws Exception {
final String[] expected= {
"m123(void)", "m12(void)", "m13(void)", "m23(void)", "m1protected(void)",
"m2protected(void)", "m2private(void)"
};
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//namespace ns { class _friend_class { C3* x; void m() {x->m/*cursor*/ // Not a friend due to namespace
public void testTypes_FakeFriendClass() throws Exception {
final String[] expected= {
"m123(void)", "m12(void)", "m13(void)", "m23(void)"
};
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void _friend_function(C3* x) { x->m/*cursor*/
public void testTypes_FriendFunction() throws Exception {
final String[] expected= {
"m123(void)", "m12(void)", "m13(void)", "m23(void)", "m1protected(void)",
"m2protected(void)", "m2private(void)"
};
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void _friend_function(C2* x) { x->m/*cursor*/ // Not a friend due to parameter type mismatch
public void testTypes_FakeFriendFunction() throws Exception {
final String[] expected= {
"m123(void)", "m12(void)", "m13(void)", "m23(void)"
};
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void C2::f() {T/*cursor*/
public void testTypes_MethodScope() throws Exception {
final String[] expected= {
"T1", "T2", "T3", "TClass"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//namespace ns {void nsfunc(){C/*cursor*/
@ -415,8 +422,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"C1", "C2", "C3", "CNS"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//namespace ns {void gfunc(){::C/*cursor*/
@ -424,8 +430,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"C1", "C2", "C3"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {e/*cursor*/
@ -433,8 +438,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"e11", "e12", "E1"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void C3::f() {e/*cursor*/
@ -442,8 +446,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"e11", "e12", "e21", "e22", "E1", "E2"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {C3* l1; l1->C/*cursor*/
@ -452,8 +455,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"C3", "C2", "C1"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {C2* l1; l1->C/*cursor*/
@ -462,8 +464,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"C2", "C1"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {C3* l1; l1->C3::fMySelf->iam/*cursor*/
@ -472,8 +473,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"iam3(void)", "iam2(void)", "iam1(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {C3* l1; l1->C2::fMySelf->iam/*cursor*/
@ -482,8 +482,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"iam2(void)", "iam1(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {C3* l1; l1->C1::fMySelf->iam/*cursor*/
@ -491,8 +490,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"iam1(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {C3* l1; l1->T3::fMySelf->iam/*cursor*/
@ -501,8 +499,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"iam3(void)", "iam2(void)", "iam1(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {C3* l1; l1->T2::fMySelf->iam/*cursor*/
@ -511,8 +508,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"iam2(void)", "iam1(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {C3* l1; l1->T1::fMySelf->iam/*cursor*/
@ -520,8 +516,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"iam1(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {C1().iam/*cursor*/
@ -529,8 +524,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"iam1(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {C1 c; (&c)->iam/*cursor*/
@ -538,8 +532,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"iam1(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {C1* c; (*c).iam/*cursor*/
@ -547,8 +540,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"iam1(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {C1** c; (**c).iam/*cursor*/
@ -556,16 +548,14 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"iam1(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {C1** c; (*c)->iam/*cursor*/
public void testDereferencingOperator3() throws Exception {
final String[] expected= {
"iam1(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {C1* c; c[0].iam/*cursor*/
@ -573,32 +563,28 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"iam1(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {C1** c; c[0][1].iam/*cursor*/
public void testArrayAccessOperator2() throws Exception {
final String[] expected= {
"iam1(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {C1** c; c[0]->iam/*cursor*/
public void testArrayAccessOperator3() throws Exception {
final String[] expected= {
"iam1(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {C1* c; (&c[0])->iam/*cursor*/
public void testArrayAccessOperator4() throws Exception {
final String[] expected= {
"iam1(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {void* c; ((C1*)c)->iam/*cursor*/
@ -606,16 +592,14 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"iam1(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void g(int a) {}; void f() {void* c; g(((C1*)c)->iam/*cursor*/
public void testCasts2() throws Exception {
final String[] expected= {
"iam1(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {C1* c; c++->iam/*cursor*/
@ -623,40 +607,35 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"iam1(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {C1* c; (*++c).iam/*cursor*/
public void testPointerArithmetic2() throws Exception {
final String[] expected= {
"iam1(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {C1* c; c--->iam/*cursor*/
public void testPointerArithmetic3() throws Exception {
final String[] expected= {
"iam1(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {C1 c; (&c+1)->iam/*cursor*/
public void testPointerArithmetic4() throws Exception {
final String[] expected= {
"iam1(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {C1 c; (&c-1)->iam/*cursor*/
public void testPointerArithmetic5() throws Exception {
final String[] expected= {
"iam1(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void f() {int localVar=0; if (*cond && somefunc(&local/*cursor*/
@ -664,8 +643,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"localVar"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//int a[] = {1,2}; void f(int _0306_b) {_0306_b/*cursor*/
@ -673,16 +651,14 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"_0306_b"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//int a[] = {1,2}; void f(int b) {int _0306_b[] = {2,3}; _0306_b/*cursor*/
public void testCuttingInput2() throws Exception {
final String[] expected= {
"_0306_b"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//enum EnumType function() {int _031209_v; _031209/*cursor*/
@ -690,8 +666,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"_031209_v"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//namespace ns {void x() {NSCO/*cursor*/
@ -699,16 +674,14 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"NSCONST"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void ns::CNS::mcns(){NSCO/*cursor*/
public void testAccessToNamespaceFromClassMember2() throws Exception {
final String[] expected= {
"NSCONST"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//#i/*cursor*/
@ -716,8 +689,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"#if", "#ifdef", "#ifndef", "#include"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//# d/*cursor*/
@ -734,8 +706,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"defined"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void gfunc(){TClass<int> t(0); t.a/*cursor*/
@ -744,8 +715,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"add(int)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void gfunc(){C3 c3; c3.t/*cursor*/
@ -754,8 +724,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"tConvert(void)"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//using namespace ns;void gfunc(){NSC/*cursor*/
@ -763,8 +732,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"NSCONST"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_ID_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS);
}
//void gfunc(){n/*cursor*/
@ -772,8 +740,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"ns::"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_REP_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_REP_STRINGS);
}
//using namespace /*cursor*/
@ -781,8 +748,7 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= {
"ns"
};
assertCompletionResults(fCursorOffset, expected,
AbstractContentAssistTest.COMPARE_REP_STRINGS);
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_REP_STRINGS);
}
//// to_be_replaced_