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
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue