diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/prefix/BasicCompletionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/prefix/BasicCompletionTest.java index dcb7164927e..4938dd819bf 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/prefix/BasicCompletionTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/prefix/BasicCompletionTest.java @@ -275,4 +275,15 @@ public class BasicCompletionTest extends CompletionTestBase { String[] expected= {}; checkCompletion(code, false, expected); } + + // struct A { + // A(int, char, int){} + // }; + // struct B : A { + // B() : A + public void testCompletionInCtorOfMemberInitializer_327064() throws Exception { + String code = getAboveComment(); + String[] expected= {"A"}; + checkNonPrefixCompletion(code, true, expected); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/prefix/CompletionTestBase.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/prefix/CompletionTestBase.java index f6fc2a3194d..183f4e15b51 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/prefix/CompletionTestBase.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/prefix/CompletionTestBase.java @@ -94,9 +94,17 @@ public class CompletionTestBase extends BaseTestCase { } protected void checkCompletion(String code, boolean isCpp, String[] expected) throws ParserException { - IASTCompletionNode node = isCpp ? getGPPCompletionNode(code) : getGCCCompletionNode(code); + checkCompletion(code, true, isCpp, expected); + } + + protected void checkNonPrefixCompletion(String code, boolean isCpp, String[] expected) throws ParserException { + checkCompletion(code, false, isCpp, expected); + } + + private void checkCompletion(String code, boolean isPrefix, boolean isCpp, String[] expected) throws ParserException { + IASTCompletionNode node = isCpp ? getGPPCompletionNode(code) : getGCCCompletionNode(code); assertNotNull(node); - List bindings= proposeBindings(node); + List bindings= proposeBindings(node, isPrefix); String[] names= getSortedNames(bindings); int len= Math.min(expected.length, names.length); for (int i = 0; i < len; i++) { @@ -131,7 +139,7 @@ public class CompletionTestBase extends BaseTestCase { return TestSourceReader.getContentsForTest(plugin.getBundle(), "parser", getClass(), getName(), sections); } - protected List proposeBindings(IASTCompletionNode completionNode) { + protected List proposeBindings(IASTCompletionNode completionNode, boolean isPrefix) { List proposals = new ArrayList(); boolean handleMacros= false; IASTName[] names = completionNode.getNames(); @@ -145,7 +153,7 @@ public class CompletionTestBase extends BaseTestCase { if (astContext == null) { continue; } - IBinding[] bindings = astContext.findBindings(names[i], true); + IBinding[] bindings = astContext.findBindings(names[i], isPrefix); if (bindings != null) for (int j = 0; j < bindings.length; ++j) proposals.add(bindings[j]); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConstructorChainInitializer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConstructorChainInitializer.java index 10f652a8b32..379a0013a63 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConstructorChainInitializer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConstructorChainInitializer.java @@ -12,8 +12,6 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; -import java.util.Arrays; - import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTImplicitName; @@ -24,14 +22,16 @@ import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.ICPPASTCompletionContext; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; +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.ICPPNamespace; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.parser.util.ArrayUtil; +import org.eclipse.cdt.core.parser.util.CharArraySet; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; @@ -131,28 +131,16 @@ public class CPPASTConstructorChainInitializer extends ASTNode implements public IBinding[] findBindings(IASTName n, boolean isPrefix, String[] namespaces) { IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix, namespaces); - ICPPASTBaseSpecifier[] baseClasses = null; - + CharArraySet baseClasses = null; for (int i = 0; i < bindings.length; i++) { - if ((bindings[i] instanceof ICPPField) || (bindings[i] instanceof ICPPNamespace)) { - continue; - } else if (bindings[i] instanceof ICPPConstructor) { - if (baseClasses == null) { + final IBinding b = bindings[i]; + if ((b instanceof ICPPField) || (b instanceof ICPPNamespace)) { + // OK, keep binding. + } else if (b instanceof ICPPConstructor || b instanceof ICPPClassType) { + if (baseClasses == null) baseClasses = getBaseClasses(n); - } - boolean isBaseClassConstructor = false; - if (baseClasses != null) { - for (ICPPASTBaseSpecifier b : baseClasses) { - char[] bindingName = bindings[i].getNameCharArray(); - char[] baseName = b.getName().getLastName().getSimpleID(); - if (Arrays.equals(bindingName, baseName)) { - isBaseClassConstructor = true; - break; - } - } - } - - if (!isBaseClassConstructor) { + + if (!baseClasses.containsKey(b.getNameCharArray())) { bindings[i] = null; } } else { @@ -162,14 +150,17 @@ public class CPPASTConstructorChainInitializer extends ASTNode implements return (IBinding[]) ArrayUtil.removeNulls(IBinding.class, bindings); } - private ICPPASTBaseSpecifier[] getBaseClasses(IASTName name) { + private CharArraySet getBaseClasses(IASTName name) { + CharArraySet result= new CharArraySet(2); for (IASTNode parent = name.getParent(); parent != null; parent = parent.getParent()) { if (parent instanceof ICPPASTCompositeTypeSpecifier) { ICPPASTCompositeTypeSpecifier specifier = (ICPPASTCompositeTypeSpecifier) parent; - return specifier.getBaseSpecifiers(); + for (ICPPASTBaseSpecifier bs : specifier.getBaseSpecifiers()) { + result.put(bs.getName().getLastName().getSimpleID()); + } } } - return null; + return result; } public boolean isPackExpansion() {