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:
parent
c1c02b297b
commit
fea0a6163a
4 changed files with 73 additions and 22 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue