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

@ -371,4 +371,11 @@ public class BasicCompletionTest extends CompletionTestBase {
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;
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.IBinding;
import org.eclipse.cdt.core.dom.ast.c.ICASTFieldDesignator;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
/**
* Implementation of field designators
*/
public class CASTFieldDesignator extends ASTNode implements ICASTFieldDesignator {
public class CASTFieldDesignator extends ASTNode implements ICASTFieldDesignator, IASTCompletionContext {
private IASTName name;
@ -74,4 +76,8 @@ public class CASTFieldDesignator extends ASTNode implements ICASTFieldDesignator
return true;
}
public IBinding[] findBindings(IASTName n, boolean isPrefix) {
return CVisitor.findBindingsForContentAssist(n, isPrefix);
}
}

View file

@ -607,26 +607,31 @@ public class CVisitor extends ASTQueries {
}
if (type != null && type instanceof ICompositeType) {
final ICompositeType ct = (ICompositeType) type;
if (type instanceof IIndexBinding) {
type= ((CASTTranslationUnit) fieldReference.getTranslationUnit()).mapToASTType((ICompositeType) type);
type= ((CASTTranslationUnit) fieldReference.getTranslationUnit()).mapToASTType(ct);
}
if (prefix) {
IBinding[] result = null;
char[] p = fieldReference.getFieldName().toCharArray();
IContentAssistMatcher matcher = ContentAssistMatcherFactory.getInstance().createMatcher(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 findFieldsByPrefix(ct, p);
}
return ((ICompositeType) type).findField(fieldReference.getFieldName().toString());
return ct.findField(fieldReference.getFieldName().toString());
}
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) {
IScope scope = getContainingScope(expr);
IBinding[] bs = scope.find(PTRDIFF_T);
@ -1463,6 +1468,8 @@ public class CVisitor extends ASTQueries {
if (prop == IASTFieldReference.FIELD_NAME) {
result = (IBinding[]) findBinding((IASTFieldReference) name.getParent(), isPrefix);
} else if (prop == ICASTFieldDesignator.FIELD_NAME) {
result = findBindingForContentAssist((ICASTFieldDesignator) name.getParent(), isPrefix);
} else {
IScope scope= getContainingScope(name);
try {
@ -1477,7 +1484,35 @@ public class CVisitor extends ASTQueries {
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());
// 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.
result.addClause(clause);
} else {
// Gnu extension: the assign operator is optional
if (LT(1) == IToken.tASSIGN)
consume(IToken.tASSIGN);
IASTInitializerClause clause= initClause(false);
ICASTDesignatedInitializer desigInitializer = nodeFactory.newDesignatedInitializer(clause);
ICASTDesignatedInitializer desigInitializer = nodeFactory.newDesignatedInitializer((IASTInitializerClause) null);
setRange(desigInitializer, designator.get(0));
adjustLength(desigInitializer, clause);
for (ICASTDesignator d : designator) {
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);
}