From be4c1f9cf23228a3705a80c1dabd661acd15b5c1 Mon Sep 17 00:00:00 2001 From: Sergey Prigogin Date: Sun, 11 Oct 2009 06:24:20 +0000 Subject: [PATCH] Filtering by visibility for content assist. Second attempt. Bug 172305. --- .../parser/tests/ast2/AccessControlTests.java | 109 +++++++ .../parser/tests/ast2/DOMParserTestSuite.java | 1 + .../core/dom/parser/cpp/ClassTypeHelper.java | 61 +++- .../parser/cpp/semantics/AccessContext.java | 240 +++++++++++++++ .../parser/cpp/semantics/CPPSemantics.java | 25 +- .../dom/parser/cpp/semantics/CPPVisitor.java | 49 ++- .../parser/cpp/semantics/SemanticUtil.java | 37 ++- .../core/pdom/dom/cpp/PDOMCPPBinding.java | 41 +-- .../pdom/dom/cpp/PDOMCPPClassTemplate.java | 3 +- .../core/pdom/dom/cpp/PDOMCPPClassType.java | 3 +- .../core/pdom/dom/cpp/PDOMCPPEnumeration.java | 3 +- .../CompletionTest_AnonymousTypes.java | 2 +- .../text/contentassist2/CompletionTests.java | 278 ++++++++---------- .../DOMCompletionProposalComputer.java | 22 +- 14 files changed, 632 insertions(+), 242 deletions(-) create mode 100644 core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AccessControlTests.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AccessContext.java diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AccessControlTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AccessControlTests.java new file mode 100644 index 00000000000..403e5fbbb58 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AccessControlTests.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright (c) 2009 Google, Inc and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sergey Prigogin (Google) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.parser.tests.ast2; + +import junit.framework.TestSuite; + +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.parser.ParserLanguage; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.AccessContext; +import org.eclipse.cdt.internal.core.parser.ParserException; + +public class AccessControlTests extends AST2BaseTest { + + protected class AccessAssertionHelper extends BindingAssertionHelper { + AccessAssertionHelper(String contents) throws ParserException { + super(contents, true); + } + + void assertAccessible(String section, int len) { + IASTName name = findName(section, len); + IBinding binding = name.resolveBinding(); + assertNotNull(binding); + assertTrue(AccessContext.isAccessible(binding, name)); + } + + void assertNotAccessible(String section, int len) { + IASTName name = findName(section, len); + IBinding binding = name.resolveBinding(); + assertNotNull(binding); + assertFalse(AccessContext.isAccessible(binding, name)); + } + } + + public AccessControlTests() { + } + + public AccessControlTests(String name) { + super(name); + } + + public static TestSuite suite() { + return suite(AccessControlTests.class); + } + + // class A { + // public: + // int a; + // }; + // class B : private A { + // friend void test(); + // int b; + // }; + // class C : protected B { + // }; + // void test() { + // class D : public C { + // void m() { + // a; //1 + // b; //1 + // } + // }; + // B b; + // b.a; //2 + // b.b; //2 + // C c; + // c.a; //3 + // c.b; //3 + // } + public void testFriends() throws Exception { + final String code = getAboveComment(); + parseAndCheckBindings(code, ParserLanguage.CPP); + AccessAssertionHelper ah= new AccessAssertionHelper(code); + ah.assertAccessible("a; //1", 1); + ah.assertAccessible("b; //1", 1); + ah.assertAccessible("a; //2", 1); + ah.assertAccessible("b; //2", 1); + ah.assertNotAccessible("a; //3", 1); + ah.assertNotAccessible("b; //3", 1); + } + + // class A { + // public: + // int a; + // }; + // + // class B : public A { + // private: + // int a; + // }; + // + // void test(B x) { + // x.a = 0; + // } + public void testHiddenMember() throws Exception { + final String code = getAboveComment(); + parseAndCheckBindings(code, ParserLanguage.CPP); + AccessAssertionHelper ah= new AccessAssertionHelper(code); + ah.assertNotAccessible("a = 0", 1); + } +} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java index ef0874d5b5c..4d40abb89f2 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java @@ -53,6 +53,7 @@ public class DOMParserTestSuite extends TestCase { suite.addTest(FaultToleranceTests.suite()); suite.addTest(LanguageExtensionsTest.suite()); suite.addTest(ASTInactiveCodeTests.suite()); + suite.addTest(AccessControlTests.suite()); return suite; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java index 62bb7095063..26952c3e472 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java @@ -50,6 +50,7 @@ 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.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; @@ -65,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; /** @@ -122,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 true if binding is a friend of classType. + * @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 @@ -207,22 +244,28 @@ public class ClassTypeHelper { return (ICPPField[]) ArrayUtil.trim(ICPPField.class, result); } - public static ICPPClassType[] getAllBases(ICPPClassType ct) throws DOMException { + /** + * Returns all direct and indirect base classes that have at least a given visibility level. + * @param classType a class + * @return An array of visible base classes in arbitrary order. + * @throws DOMException + */ + public static ICPPClassType[] getAllBases(ICPPClassType classType) throws DOMException { HashSet result= new HashSet(); - result.add(ct); - getAllBases(ct, result); - result.remove(ct); + result.add(classType); + getAllBases(classType, result); + result.remove(classType); return result.toArray(new ICPPClassType[result.size()]); } - private static void getAllBases(ICPPClassType ct, HashSet result) throws DOMException { - ICPPBase[] bases= ct.getBases(); + private static void getAllBases(ICPPClassType classType, HashSet 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); + final ICPPClassType baseClass = (ICPPClassType) b; + if (result.add(baseClass)) { + getAllBases(baseClass, result); } } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AccessContext.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AccessContext.java new file mode 100644 index 00000000000..ec1d9bb639c --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AccessContext.java @@ -0,0 +1,240 @@ +/******************************************************************************* + * Copyright (c) 2009 Google, Inc and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sergey Prigogin (Google) - initial API and implementation + *******************************************************************************/ +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.IASTName; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.ICompositeType; +import org.eclipse.cdt.core.dom.ast.IProblemBinding; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; +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.ICPPMember; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; +import org.eclipse.cdt.core.parser.util.ArrayUtil; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; + +/** + * The context that determines access to private and protected class members. + */ +public class AccessContext { + private static final int v_private = ICPPMember.v_private; + private static final int v_protected = ICPPMember.v_protected; + public static final int v_public = ICPPMember.v_public; + + /** + * Checks if a binding is accessible from a given name. + * @param binding A binding to check access for. + * @param from A name corresponding to the binding. + * @return true if the binding is accessible. + */ + public static boolean isAccessible(IBinding binding, IASTName from) { + return new AccessContext(from).isAccessible(binding); + } + + private final IASTName name; + /** + * A chain of nested classes or/and a function that determine accessibility of private/protected members + * by participating in friendship or class inheritance relationships. If both, classes and a function + * are present in the context, the outermost class has to be local to the function. + * {@link "http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#45"} + */ + private IBinding[] context; + /** + * A class through which the bindings are accessed (11.2.4). + */ + private ICPPClassType namingClass; + private DOMException initializationException; + + public AccessContext(IASTName name) { + this.name = name; + } + + /** + * Checks if a binding is accessible in a given context. + * @param binding A binding to check access for. + * @return true if the binding is accessible. + */ + public boolean isAccessible(IBinding binding) { + try { + IBinding owner; + while ((owner = binding.getOwner()) instanceof ICompositeType && + ((ICompositeType) owner).isAnonymous()) { + binding = owner; + } + if (!(owner instanceof ICPPClassType)) { + return true; // The binding is not a class member. + } + if (!Initialize()) { + return true; // Assume visibility if anything goes wrong. + } + if (namingClass == null) { + return true; + } + return isAccessible(binding, (ICPPClassType) owner, namingClass, v_public, 0); + } catch (DOMException e) { + CCorePlugin.log(e); + } + return true; + } + + /** + * @return true if initialization succeeded. + */ + private boolean Initialize() { + if (context == null) { + if (initializationException != null) { + return false; + } + try { + namingClass = getNamingClass(name); + context = getContext(name); + } catch (DOMException e) { + CCorePlugin.log(e); + initializationException = e; + return false; + } + } + return true; + } + + private boolean isAccessible(IBinding binding, ICPPClassType owner, ICPPClassType derivedClass, + int accessLevel, int depth) throws DOMException { + if (depth > CPPSemantics.MAX_INHERITANCE_DEPTH) + return false; + + accessLevel = getMemberAccessLevel(derivedClass, accessLevel); + if (owner.isSameType(derivedClass)) { + if (binding instanceof ICPPMember) { + return isAccessible(((ICPPMember) binding).getVisibility(), accessLevel); + } else { + // TODO(sprigogin): Handle visibility of nested types + return true; + } + } else { + ICPPBase[] bases = derivedClass.getBases(); + if (bases != null) { + for (ICPPBase base : bases) { + if (base instanceof IProblemBinding) { + continue; + } + IBinding baseBinding = base.getBaseClass(); + if (!(baseBinding instanceof ICPPClassType)) { + continue; + } + if (!isAccessible(base.getVisibility(), accessLevel)) { + continue; + } + if (isAccessible(binding, owner, (ICPPClassType) baseBinding, + accessLevel == v_private ? v_protected : accessLevel, depth + 1)) { + return true; + } + } + } + return false; + } + } + + /** + * Returns access level to the members of a class. + * @param classType A class + * @param inheritedAccessLevel Access level inherited from derived class. One of: v_public, v_protected, + * v_private. + * @return One of: v_public, v_protected, v_private. + */ + private int getMemberAccessLevel(ICPPClassType classType, int inheritedAccessLevel) throws DOMException { + int accessLevel = inheritedAccessLevel; + for (IBinding contextBinding : context) { + if (ClassTypeHelper.isFriend(contextBinding, classType)) + return v_private; + + if (accessLevel == v_public && contextBinding instanceof ICPPClassType) { + ICPPClassType contextClass = (ICPPClassType) contextBinding; + if (isAccessibleBaseClass(classType, contextClass, 0)) + accessLevel = v_protected; + } + } + return accessLevel; + } + + private boolean isAccessibleBaseClass(ICPPClassType classType, ICPPClassType defived, int depth) + throws DOMException { + if (depth > CPPSemantics.MAX_INHERITANCE_DEPTH) + return false; + + if (defived.isSameType(classType)) + return true; + + ICPPBase[] bases = defived.getBases(); + if (bases != null) { + for (ICPPBase base : bases) { + if (base instanceof IProblemBinding) { + continue; + } + IBinding baseClass = base.getBaseClass(); + if (!(baseClass instanceof ICPPClassType)) { + continue; + } + if (depth > 0 && !isAccessible(base.getVisibility(), v_protected)) { + continue; + } + if (isAccessibleBaseClass(classType, (ICPPClassType) baseClass, depth + 1)) { + return true; + } + } + } + return false; + } + + private static ICPPClassType getNamingClass(IASTName name) throws DOMException { + LookupData data = new LookupData(name); + ICPPScope scope= CPPSemantics.getLookupScope(name, data); + while (scope != null && !(scope instanceof ICPPClassScope)) { + scope = CPPSemantics.getParentScope(scope, data.tu); + } + if (scope instanceof ICPPClassScope) { + return ((ICPPClassScope) scope).getClassType(); + } + return null; + } + + private static IBinding[] getContext(IASTName name) throws DOMException { + IBinding[] accessibilityContext = IBinding.EMPTY_BINDING_ARRAY; + for (IBinding binding = CPPVisitor.findEnclosingFunctionOrClass(name); + 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 ICPPFunction || binding instanceof ICPPClassType) { + accessibilityContext = ArrayUtil.append(accessibilityContext, binding); + } + } + return ArrayUtil.trim(accessibilityContext); + } + + /** + * Checks if objects with the given visibility are accessible at the given access level. + * @param visibility one of: v_public, v_protected, v_private. + * @param accessLevel one of: v_public, v_protected, v_private. + * @return true if the access level is sufficiently high. + */ + private static boolean isAccessible(int visibility, int accessLevel) { + // Note the ordering of numeric visibility values: v_public < v_protected < v_private. + return accessLevel >= visibility; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index e9619f8bf2e..8a9d4942c4a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -637,7 +637,7 @@ public class CPPSemantics { return (ICPPNamespaceScope) scope; } - static private ICPPScope getLookupScope(IASTName name, LookupData data) throws DOMException { + static ICPPScope getLookupScope(IASTName name, LookupData data) throws DOMException { IASTNode parent = name.getParent(); IScope scope = null; if (parent instanceof ICPPASTBaseSpecifier) { @@ -1021,7 +1021,7 @@ public class CPPSemantics { return ((ICPPASTTemplateDeclaration) parent).getScope(); } - private static ICPPScope getParentScope(IScope scope, CPPASTTranslationUnit unit) throws DOMException { + static ICPPScope getParentScope(IScope scope, CPPASTTranslationUnit unit) throws DOMException { IScope parentScope= scope.getParent(); // the index cannot return the translation unit as parent scope if (unit != null) { @@ -1035,7 +1035,6 @@ public class CPPSemantics { return (ICPPScope) parentScope; } - /** * Stores the using directive with the scope where the members of the nominated namespace will appear. * In case of an unqualified lookup the transitive directives are stored, also. This is important because @@ -1675,9 +1674,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; @@ -1696,7 +1695,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()); @@ -2835,13 +2834,13 @@ public class CPPSemantics { 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; @@ -2850,28 +2849,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) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index 13aa2e1ba00..65878a0d261 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -872,8 +872,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 null if the given node + * is not part of a function definition. */ public static ICPPASTFunctionDefinition findEnclosingFunctionDefinition(IASTNode node) { while (node != null) { @@ -1086,7 +1086,7 @@ public class CPPVisitor extends ASTQueries { } return null; } - + public static class CollectProblemsAction extends CPPASTVisitor { { shouldVisitDeclarations = true; @@ -1872,8 +1872,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); } @@ -1988,12 +1990,36 @@ public class CPPVisitor extends ASTQueries { return null; } + /** + * Searches for the function or class enclosing the given node. May return null. + */ + 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; @@ -2003,16 +2029,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 null, if the declaration - * is not enclosed by any of the above constructs. + * Searches for the first class, namespace, or function, if allowFunction + * is true, enclosing the declaration the provided node belongs to and returns + * the binding for it. Returns null, if the declaration is not enclosed by any + * of the above constructs. */ public static IBinding findDeclarationOwner(IASTNode node, boolean allowFunction) { // Search for declaration @@ -2026,7 +2053,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; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java index 231a9ea5c67..ea58755f8f6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java @@ -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 true 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; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPBinding.java index f9cb5c01a3a..46ffae81f15 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPBinding.java @@ -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 result = new ArrayList(); try { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplate.java index 45e64de554d..8a17263bb9a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplate.java @@ -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; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java index d2402aaf044..78a9033a3e1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java @@ -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); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeration.java index 43daf76a7e5..f78a9fc646f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeration.java @@ -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); diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTest_AnonymousTypes.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTest_AnonymousTypes.java index 9ba7cfd6e8c..e6080baf10e 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTest_AnonymousTypes.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTest_AnonymousTypes.java @@ -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"; diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java index cb8a5406f06..b3ea0580088 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java @@ -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 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 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_ diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/DOMCompletionProposalComputer.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/DOMCompletionProposalComputer.java index 55c80de91fc..7ed04acb6f9 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/DOMCompletionProposalComputer.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/DOMCompletionProposalComputer.java @@ -9,6 +9,7 @@ * QNX - Initial API and implementation * Markus Schorn (Wind River Systems) * Anton Leherbauer (Wind River Systems) + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.ui.text.contentassist; @@ -75,6 +76,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBuiltinVariable; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitFunction; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitMethod; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitTypedef; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.AccessContext; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates.CPPImplicitFunctionTemplate; import org.eclipse.cdt.internal.ui.viewsupport.CElementImageProvider; @@ -115,12 +117,12 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer boolean handleMacros= false; IASTName[] names = completionNode.getNames(); - for (int i = 0; i < names.length; ++i) { - if (names[i].getTranslationUnit() == null) + for (IASTName name : names) { + if (name.getTranslationUnit() == null) // The node isn't properly hooked up, must have backtracked out of this node continue; - IASTCompletionContext astContext = names[i].getCompletionContext(); + IASTCompletionContext astContext = name.getCompletionContext(); if (astContext == null) { continue; } else if (astContext instanceof IASTIdExpression @@ -129,12 +131,14 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer handleMacros = prefix.length() > 0; } - IBinding[] bindings = astContext.findBindings( - names[i], !context.isContextInformationStyle()); + IBinding[] bindings = astContext.findBindings(name, !context.isContextInformationStyle()); if (bindings != null) { - for (int j = 0; j < bindings.length; ++j) - handleBinding(bindings[j], context, prefix, astContext, proposals); + AccessContext accessibilityContext = new AccessContext(name); + for (IBinding binding : bindings) { + if (accessibilityContext.isAccessible(binding)) + handleBinding(binding, context, prefix, astContext, proposals); + } } } @@ -292,7 +296,7 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer && !(binding instanceof CPPImplicitMethod)) { return; } - + if (!isAnonymousBinding(binding)) { final String name = binding.getName(); final int baseRelevance= computeBaseRelevance(prefix, name); @@ -340,7 +344,7 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer } else { int relevance= 0; try { - switch(classType.getKey()) { + switch (classType.getKey()) { case ICPPClassType.k_class: relevance= RelevanceConstants.CLASS_TYPE_RELEVANCE; break;