1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-08 16:55:38 +02:00

Bug 327064 - Content assist within member initializer.

This commit is contained in:
Markus Schorn 2010-10-07 08:54:27 +00:00
parent c1318e84f4
commit 4ff02dcc5d
3 changed files with 40 additions and 30 deletions

View file

@ -275,4 +275,15 @@ public class BasicCompletionTest extends CompletionTestBase {
String[] expected= {}; String[] expected= {};
checkCompletion(code, false, 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);
}
} }

View file

@ -94,9 +94,17 @@ public class CompletionTestBase extends BaseTestCase {
} }
protected void checkCompletion(String code, boolean isCpp, String[] expected) throws ParserException { 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); assertNotNull(node);
List<IBinding> bindings= proposeBindings(node); List<IBinding> bindings= proposeBindings(node, isPrefix);
String[] names= getSortedNames(bindings); String[] names= getSortedNames(bindings);
int len= Math.min(expected.length, names.length); int len= Math.min(expected.length, names.length);
for (int i = 0; i < len; i++) { 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); return TestSourceReader.getContentsForTest(plugin.getBundle(), "parser", getClass(), getName(), sections);
} }
protected List<IBinding> proposeBindings(IASTCompletionNode completionNode) { protected List<IBinding> proposeBindings(IASTCompletionNode completionNode, boolean isPrefix) {
List<IBinding> proposals = new ArrayList<IBinding>(); List<IBinding> proposals = new ArrayList<IBinding>();
boolean handleMacros= false; boolean handleMacros= false;
IASTName[] names = completionNode.getNames(); IASTName[] names = completionNode.getNames();
@ -145,7 +153,7 @@ public class CompletionTestBase extends BaseTestCase {
if (astContext == null) { if (astContext == null) {
continue; continue;
} }
IBinding[] bindings = astContext.findBindings(names[i], true); IBinding[] bindings = astContext.findBindings(names[i], isPrefix);
if (bindings != null) if (bindings != null)
for (int j = 0; j < bindings.length; ++j) for (int j = 0; j < bindings.length; ++j)
proposals.add(bindings[j]); proposals.add(bindings[j]);

View file

@ -12,8 +12,6 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; 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.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName; 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.IBinding;
import org.eclipse.cdt.core.dom.ast.ICPPASTCompletionContext; 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;
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.ICPPASTConstructorChainInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer; 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.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.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; 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.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.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.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; 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) { public IBinding[] findBindings(IASTName n, boolean isPrefix, String[] namespaces) {
IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix, namespaces); IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix, namespaces);
ICPPASTBaseSpecifier[] baseClasses = null; CharArraySet baseClasses = null;
for (int i = 0; i < bindings.length; i++) { for (int i = 0; i < bindings.length; i++) {
if ((bindings[i] instanceof ICPPField) || (bindings[i] instanceof ICPPNamespace)) { final IBinding b = bindings[i];
continue; if ((b instanceof ICPPField) || (b instanceof ICPPNamespace)) {
} else if (bindings[i] instanceof ICPPConstructor) { // OK, keep binding.
if (baseClasses == null) { } else if (b instanceof ICPPConstructor || b instanceof ICPPClassType) {
if (baseClasses == null)
baseClasses = getBaseClasses(n); 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; bindings[i] = null;
} }
} else { } else {
@ -162,14 +150,17 @@ public class CPPASTConstructorChainInitializer extends ASTNode implements
return (IBinding[]) ArrayUtil.removeNulls(IBinding.class, bindings); 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()) { for (IASTNode parent = name.getParent(); parent != null; parent = parent.getParent()) {
if (parent instanceof ICPPASTCompositeTypeSpecifier) { if (parent instanceof ICPPASTCompositeTypeSpecifier) {
ICPPASTCompositeTypeSpecifier specifier = (ICPPASTCompositeTypeSpecifier) parent; 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() { public boolean isPackExpansion() {