1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 353281: Content assist for designated initializers

This commit is contained in:
Markus Schorn 2011-08-11 16:24:00 +02:00
parent c1c02b297b
commit fea0a6163a
4 changed files with 73 additions and 22 deletions

View file

@ -370,5 +370,12 @@ public class BasicCompletionTest extends CompletionTestBase {
checkCompletion(code, false, expected); checkCompletion(code, false, expected);
checkCompletion(code, true, expected); checkCompletion(code, true, expected);
} }
// struct foo { int axx;};
// struct foo bar = {.a
public void testCompletionInDesignatedInitializor_353281() throws Exception {
String code = getAboveComment();
String[] expected= {"axx"};
checkCompletion(code, false, expected);
}
} }

View file

@ -13,14 +13,16 @@
package org.eclipse.cdt.internal.core.dom.parser.c; package org.eclipse.cdt.internal.core.dom.parser.c;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTCompletionContext;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.c.ICASTFieldDesignator; import org.eclipse.cdt.core.dom.ast.c.ICASTFieldDesignator;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
/** /**
* Implementation of field designators * Implementation of field designators
*/ */
public class CASTFieldDesignator extends ASTNode implements ICASTFieldDesignator { public class CASTFieldDesignator extends ASTNode implements ICASTFieldDesignator, IASTCompletionContext {
private IASTName name; private IASTName name;
@ -74,4 +76,8 @@ public class CASTFieldDesignator extends ASTNode implements ICASTFieldDesignator
return true; return true;
} }
public IBinding[] findBindings(IASTName n, boolean isPrefix) {
return CVisitor.findBindingsForContentAssist(n, isPrefix);
}
} }

View file

@ -607,25 +607,30 @@ public class CVisitor extends ASTQueries {
} }
if (type != null && type instanceof ICompositeType) { if (type != null && type instanceof ICompositeType) {
final ICompositeType ct = (ICompositeType) type;
if (type instanceof IIndexBinding) { if (type instanceof IIndexBinding) {
type= ((CASTTranslationUnit) fieldReference.getTranslationUnit()).mapToASTType((ICompositeType) type); type= ((CASTTranslationUnit) fieldReference.getTranslationUnit()).mapToASTType(ct);
} }
if (prefix) { if (prefix) {
IBinding[] result = null;
char[] p = fieldReference.getFieldName().toCharArray(); char[] p = fieldReference.getFieldName().toCharArray();
IContentAssistMatcher matcher = ContentAssistMatcherFactory.getInstance().createMatcher(p); return findFieldsByPrefix(ct, p);
IField[] fields = ((ICompositeType) type).getFields();
for (IField field : fields) {
if (matcher.match(field.getNameCharArray())) {
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, field);
}
}
return ArrayUtil.trim(IBinding.class, result);
} }
return ((ICompositeType) type).findField(fieldReference.getFieldName().toString()); return ct.findField(fieldReference.getFieldName().toString());
} }
return null; return null;
} }
public static IBinding[] findFieldsByPrefix(final ICompositeType ct, char[] p) {
IBinding[] result = null;
IContentAssistMatcher matcher = ContentAssistMatcherFactory.getInstance().createMatcher(p);
IField[] fields = ct.getFields();
for (IField field : fields) {
if (matcher.match(field.getNameCharArray())) {
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, field);
}
}
return (IBinding[]) ArrayUtil.trim(IBinding.class, result);
}
static IType getPtrDiffType(IASTBinaryExpression expr) { static IType getPtrDiffType(IASTBinaryExpression expr) {
IScope scope = getContainingScope(expr); IScope scope = getContainingScope(expr);
@ -1463,6 +1468,8 @@ public class CVisitor extends ASTQueries {
if (prop == IASTFieldReference.FIELD_NAME) { if (prop == IASTFieldReference.FIELD_NAME) {
result = (IBinding[]) findBinding((IASTFieldReference) name.getParent(), isPrefix); result = (IBinding[]) findBinding((IASTFieldReference) name.getParent(), isPrefix);
} else if (prop == ICASTFieldDesignator.FIELD_NAME) {
result = findBindingForContentAssist((ICASTFieldDesignator) name.getParent(), isPrefix);
} else { } else {
IScope scope= getContainingScope(name); IScope scope= getContainingScope(name);
try { try {
@ -1477,7 +1484,35 @@ public class CVisitor extends ASTQueries {
return (IBinding[]) ArrayUtil.trim(IBinding.class, result); return (IBinding[]) ArrayUtil.trim(IBinding.class, result);
} }
public static IBinding[] findBindings(IScope scope, String name) { private static IBinding[] findBindingForContentAssist(ICASTFieldDesignator fd, boolean isPrefix) {
IASTNode blockItem = getContainingBlockItem(fd);
IASTNode parent= blockItem;
while (parent != null && !(parent instanceof IASTSimpleDeclaration))
parent= parent.getParent();
if (parent instanceof IASTSimpleDeclaration) {
IASTSimpleDeclaration simpleDecl = (IASTSimpleDeclaration) parent;
IBinding struct= null;
if (simpleDecl.getDeclSpecifier() instanceof IASTNamedTypeSpecifier) {
struct = ((IASTNamedTypeSpecifier) simpleDecl.getDeclSpecifier()).getName().resolveBinding();
} else if (simpleDecl.getDeclSpecifier() instanceof IASTElaboratedTypeSpecifier) {
struct = ((IASTElaboratedTypeSpecifier) simpleDecl.getDeclSpecifier()).getName().resolveBinding();
} else if (simpleDecl.getDeclSpecifier() instanceof IASTCompositeTypeSpecifier) {
struct = ((IASTCompositeTypeSpecifier) simpleDecl.getDeclSpecifier()).getName().resolveBinding();
}
if (struct instanceof IType) {
IType t= unwrapTypedefs((IType) struct);
if (t instanceof ICompositeType) {
return findFieldsByPrefix((ICompositeType) t, fd.getName().toCharArray());
}
}
}
return null;
}
public static IBinding[] findBindings(IScope scope, String name) {
CASTName astName = new CASTName(name.toCharArray()); CASTName astName = new CASTName(name.toCharArray());
// normal names // normal names

View file

@ -177,18 +177,21 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
// in any way add the initializer such that the actual size can be tracked. // in any way add the initializer such that the actual size can be tracked.
result.addClause(clause); result.addClause(clause);
} else { } else {
// Gnu extension: the assign operator is optional ICASTDesignatedInitializer desigInitializer = nodeFactory.newDesignatedInitializer((IASTInitializerClause) null);
if (LT(1) == IToken.tASSIGN)
consume(IToken.tASSIGN);
IASTInitializerClause clause= initClause(false);
ICASTDesignatedInitializer desigInitializer = nodeFactory.newDesignatedInitializer(clause);
setRange(desigInitializer, designator.get(0)); setRange(desigInitializer, designator.get(0));
adjustLength(desigInitializer, clause);
for (ICASTDesignator d : designator) { for (ICASTDesignator d : designator) {
desigInitializer.addDesignator(d); desigInitializer.addDesignator(d);
} }
if (LT(1) != IToken.tEOC) {
// Gnu extension: the assign operator is optional
if (LT(1) == IToken.tASSIGN)
consume(IToken.tASSIGN);
IASTInitializerClause clause= initClause(false);
desigInitializer.setOperand(clause);
adjustLength(desigInitializer, clause);
}
result.addClause(desigInitializer); result.addClause(desigInitializer);
} }