mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-09 17:25:38 +02:00
fixed bug with content assist not working on top level named type specifier
This commit is contained in:
parent
1a60090ab9
commit
17931aa374
5 changed files with 79 additions and 62 deletions
|
@ -23,34 +23,33 @@ public class BasicCompletionTest extends CompletionTestBase {
|
|||
private void testVar(IASTCompletionNode node) throws Exception {
|
||||
IASTName[] names = node.getNames();
|
||||
assertEquals(1, names.length);
|
||||
IBinding[] bindings = names[0].getCompletionContext().findBindings(
|
||||
names[0], true);
|
||||
IBinding[] bindings = names[0].getCompletionContext().findBindings(names[0], true);
|
||||
assertEquals(1, bindings.length);
|
||||
IVariable var = (IVariable)bindings[0];
|
||||
assertEquals("blah", var.getName());
|
||||
}
|
||||
|
||||
public void testVar() throws Exception {
|
||||
StringBuffer code = new StringBuffer();
|
||||
code.append("int blah = 4;");
|
||||
code.append("int two = bl");
|
||||
testVar(getGPPCompletionNode(code.toString()));
|
||||
testVar(getGCCCompletionNode(code.toString()));
|
||||
String code =
|
||||
"int blah = 4;" +
|
||||
"int two = bl";
|
||||
|
||||
testVar(getGPPCompletionNode(code));
|
||||
testVar(getGCCCompletionNode(code));
|
||||
}
|
||||
|
||||
public void testFunction() throws Exception {
|
||||
StringBuffer code = new StringBuffer();
|
||||
code.append("void func(int x) { }");
|
||||
code.append("void func2() { fu");
|
||||
String code =
|
||||
"void func(int x) { }" +
|
||||
"void func2() { fu";
|
||||
|
||||
// C++
|
||||
IASTCompletionNode node = getGPPCompletionNode(code.toString());
|
||||
IASTCompletionNode node = getGPPCompletionNode(code);
|
||||
IASTName[] names = node.getNames();
|
||||
// There are three names, one as an expression, one that isn't connected, one as a declaration
|
||||
assertEquals(3, names.length);
|
||||
// The expression points to our functions
|
||||
IBinding[] bindings = names[0].getCompletionContext().findBindings(
|
||||
names[0], true);
|
||||
IBinding[] bindings = names[0].getCompletionContext().findBindings(names[0], true);
|
||||
// There should be two since they both start with fu
|
||||
assertEquals(2, bindings.length);
|
||||
assertEquals("func", ((IFunction)bindings[0]).getName());
|
||||
|
@ -61,13 +60,12 @@ public class BasicCompletionTest extends CompletionTestBase {
|
|||
assertNull(names[2].getTranslationUnit());
|
||||
|
||||
// C
|
||||
node = getGCCCompletionNode(code.toString());
|
||||
node = getGCCCompletionNode(code);
|
||||
names = node.getNames();
|
||||
// There are two names, one as an expression, one as a declaration
|
||||
assertEquals(2, names.length);
|
||||
// The expression points to our functions
|
||||
bindings = sortBindings(names[0].getCompletionContext().findBindings(
|
||||
names[0], true));
|
||||
bindings = sortBindings(names[0].getCompletionContext().findBindings(names[0], true));
|
||||
// There should be two since they both start with fu
|
||||
assertEquals(2, bindings.length);
|
||||
assertEquals("func", ((IFunction)bindings[0]).getName());
|
||||
|
@ -77,22 +75,21 @@ public class BasicCompletionTest extends CompletionTestBase {
|
|||
}
|
||||
|
||||
public void testTypedef() throws Exception {
|
||||
StringBuffer code = new StringBuffer();
|
||||
code.append("typedef int blah;");
|
||||
code.append("bl");
|
||||
String code =
|
||||
"typedef int blah;" +
|
||||
"bl";
|
||||
|
||||
// C++
|
||||
IASTCompletionNode node = getGPPCompletionNode(code.toString());
|
||||
IASTCompletionNode node = getGPPCompletionNode(code);
|
||||
IASTName[] names = node.getNames();
|
||||
assertEquals(2, names.length);
|
||||
assertNull(names[0].getTranslationUnit());
|
||||
IBinding[] bindings = names[1].getCompletionContext().findBindings(
|
||||
names[1], true);
|
||||
IBinding[] bindings = names[1].getCompletionContext().findBindings(names[1], true);
|
||||
assertEquals(1, bindings.length);
|
||||
assertEquals("blah", ((ITypedef)bindings[0]).getName());
|
||||
|
||||
// C
|
||||
node = getGCCCompletionNode(code.toString());
|
||||
node = getGCCCompletionNode(code);
|
||||
names = node.getNames();
|
||||
assertEquals(1, names.length);
|
||||
bindings = names[0].getCompletionContext().findBindings(names[0], true);
|
||||
|
@ -101,28 +98,28 @@ public class BasicCompletionTest extends CompletionTestBase {
|
|||
}
|
||||
|
||||
public void testBug181624() throws Exception {
|
||||
StringBuffer code = new StringBuffer();
|
||||
code.append("void foo() {");
|
||||
code.append(" switch (");
|
||||
String code =
|
||||
"void foo() {" +
|
||||
" switch (";
|
||||
|
||||
// C++
|
||||
IASTCompletionNode node = getGPPCompletionNode(code.toString());
|
||||
IASTCompletionNode node = getGPPCompletionNode(code);
|
||||
assertNotNull(node);
|
||||
|
||||
// C
|
||||
node = getGCCCompletionNode(code.toString());
|
||||
node = getGCCCompletionNode(code);
|
||||
assertNotNull(node);
|
||||
|
||||
code = new StringBuffer();
|
||||
code.append("void foo() {");
|
||||
code.append(" while (");
|
||||
code =
|
||||
"void foo() {" +
|
||||
" while (";
|
||||
|
||||
// C++
|
||||
node = getGPPCompletionNode(code.toString());
|
||||
node = getGPPCompletionNode(code);
|
||||
assertNotNull(node);
|
||||
|
||||
// C
|
||||
node = getGCCCompletionNode(code.toString());
|
||||
node = getGCCCompletionNode(code);
|
||||
assertNotNull(node);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ package org.eclipse.cdt.core.lrparser.tests;
|
|||
import junit.framework.TestSuite;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTCompletionNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IFunction;
|
||||
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
||||
|
@ -24,7 +23,7 @@ import org.eclipse.cdt.core.parser.ParserLanguage;
|
|||
import org.eclipse.cdt.core.parser.tests.prefix.BasicCompletionTest;
|
||||
import org.eclipse.cdt.internal.core.parser.ParserException;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
@SuppressWarnings({"restriction", "nls"})
|
||||
public class LRCompletionBasicTest extends BasicCompletionTest {
|
||||
|
||||
public static TestSuite suite() {
|
||||
|
@ -52,41 +51,52 @@ public class LRCompletionBasicTest extends BasicCompletionTest {
|
|||
protected ILanguage getCPPLanguage() {
|
||||
return ISOCPPLanguage.getDefault();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void testFunction() throws Exception {
|
||||
StringBuffer code = new StringBuffer();
|
||||
code.append("void func(int x) { }");//$NON-NLS-1$
|
||||
code.append("void func2() { fu");//$NON-NLS-1$
|
||||
String code =
|
||||
"void func(int x) { }" +
|
||||
"void func2() { fu";
|
||||
|
||||
// C++
|
||||
IASTCompletionNode node = getGPPCompletionNode(code);
|
||||
IBinding[] bindings = LRCompletionParseTest.getBindings(node.getNames());
|
||||
|
||||
assertEquals(2, bindings.length);
|
||||
assertEquals("func", ((IFunction)bindings[0]).getName());
|
||||
assertEquals("func2", ((IFunction)bindings[1]).getName());
|
||||
|
||||
// C
|
||||
IASTCompletionNode node = getGCCCompletionNode(code.toString());
|
||||
IASTName[] names = node.getNames();
|
||||
node = getGCCCompletionNode(code);
|
||||
bindings = LRCompletionParseTest.getBindings(node.getNames());
|
||||
|
||||
// There is only one name, for now
|
||||
assertEquals(2, names.length);
|
||||
// The expression points to our functions
|
||||
IBinding[] bindings = sortBindings(names[1].getCompletionContext().findBindings(names[1], true));
|
||||
// There should be two since they both start with fu
|
||||
assertEquals(2, bindings.length);
|
||||
assertEquals("func", ((IFunction)bindings[0]).getName());//$NON-NLS-1$
|
||||
assertEquals("func2", ((IFunction)bindings[1]).getName());//$NON-NLS-1$
|
||||
|
||||
assertEquals("func", ((IFunction)bindings[0]).getName());
|
||||
assertEquals("func2", ((IFunction)bindings[1]).getName());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void testTypedef() throws Exception {
|
||||
StringBuffer code = new StringBuffer();
|
||||
code.append("typedef int blah;");//$NON-NLS-1$
|
||||
code.append("bl");//$NON-NLS-1$
|
||||
String code =
|
||||
"typedef int blah;" +
|
||||
"bl";
|
||||
|
||||
// C++
|
||||
IASTCompletionNode node = getGPPCompletionNode(code);
|
||||
IBinding[] bindings = LRCompletionParseTest.getBindings(node.getNames());
|
||||
|
||||
assertEquals(1, bindings.length);
|
||||
assertEquals("blah", ((ITypedef)bindings[0]).getName());
|
||||
|
||||
// C
|
||||
IASTCompletionNode node = getGCCCompletionNode(code.toString());
|
||||
IASTName[] names = node.getNames();
|
||||
assertEquals(1, names.length);
|
||||
IBinding[] bindings = names[0].getCompletionContext().findBindings(names[0], true);
|
||||
node = getGCCCompletionNode(code);
|
||||
bindings = LRCompletionParseTest.getBindings(node.getNames());
|
||||
|
||||
assertEquals(1, bindings.length);
|
||||
assertEquals("blah", ((ITypedef)bindings[0]).getName());//$NON-NLS-1$
|
||||
assertEquals("blah", ((ITypedef)bindings[0]).getName());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ public class LRCompletionParseTest extends TestCase {
|
|||
};
|
||||
|
||||
|
||||
protected IBinding[] getBindings(IASTName[] names) {
|
||||
public static IBinding[] getBindings(IASTName[] names) {
|
||||
List<IBinding> bindings = new ArrayList<IBinding>();
|
||||
|
||||
for(IASTName name : names)
|
||||
|
|
|
@ -28,7 +28,6 @@ public class CPPASTAmbiguousDeclarator extends CPPASTAmbiguity implements IASTDe
|
|||
|
||||
|
||||
public CPPASTAmbiguousDeclarator(IASTDeclarator ... ds) {
|
||||
System.out.println("CPPASTAmbiguousDeclarator created");
|
||||
for(IASTDeclarator declarator : ds)
|
||||
addDeclarator(declarator);
|
||||
}
|
||||
|
|
|
@ -1198,21 +1198,32 @@ public class CPPBuildASTParserAction extends BuildASTParserAction {
|
|||
List<Object> declarators = hasDeclaratorList ? astStack.closeScope() : Collections.emptyList();
|
||||
IASTDeclSpecifier declSpecifier = (IASTDeclSpecifier) astStack.pop(); // may be null
|
||||
List<IToken> ruleTokens = parser.getRuleTokens();
|
||||
IToken nameToken = null;
|
||||
|
||||
|
||||
// do not generate nodes for extra EOC tokens
|
||||
if(matchTokens(ruleTokens, tokenMap, TK_EndOfCompletion)) {
|
||||
return;
|
||||
}
|
||||
if(declSpecifier == null) { // can happen if implicit int is used
|
||||
|
||||
// In the case that a single completion token is parsed then it needs
|
||||
// to be interpreted as a named type specifier for content assist to work.
|
||||
else if(matchTokens(ruleTokens, tokenMap, TK_Completion, TK_EndOfCompletion)) {
|
||||
IASTName name = createName(parser.getLeftIToken());
|
||||
declSpecifier = nodeFactory.newCPPNamedTypeSpecifier(name, false);
|
||||
setOffsetAndLength(declSpecifier, offset(name), length(name));
|
||||
declarators = Collections.emptyList(); // throw away the bogus declarator
|
||||
}
|
||||
|
||||
// can happen if implicit int is used
|
||||
else if(declSpecifier == null) {
|
||||
declSpecifier = nodeFactory.newSimpleDeclSpecifier();
|
||||
setOffsetAndLength(declSpecifier, parser.getLeftIToken().getStartOffset(), 0);
|
||||
}
|
||||
|
||||
|
||||
// bug 80171, check for situation similar to: static var;
|
||||
// this will get parsed wrong, the following is a hack to rebuild the AST as it should have been parsed
|
||||
IToken nameToken = null;
|
||||
if(declarators.isEmpty() &&
|
||||
else if(declarators.isEmpty() &&
|
||||
declSpecifier instanceof ICPPASTNamedTypeSpecifier &&
|
||||
ruleTokens.size() >= 2 &&
|
||||
baseKind(nameToken = ruleTokens.get(ruleTokens.size() - 2)) == TK_identifier) {
|
||||
|
|
Loading…
Add table
Reference in a new issue