From 17931aa3745b8368e5cb20b39c885876ec944713 Mon Sep 17 00:00:00 2001 From: Mike Kucera Date: Mon, 5 May 2008 18:13:05 +0000 Subject: [PATCH] fixed bug with content assist not working on top level named type specifier --- .../tests/prefix/BasicCompletionTest.java | 63 +++++++++---------- .../lrparser/tests/LRCompletionBasicTest.java | 56 ++++++++++------- .../lrparser/tests/LRCompletionParseTest.java | 2 +- .../action/cpp/CPPASTAmbiguousDeclarator.java | 1 - .../action/cpp/CPPBuildASTParserAction.java | 19 ++++-- 5 files changed, 79 insertions(+), 62 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/prefix/BasicCompletionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/prefix/BasicCompletionTest.java index 680eba45710..b4e1f30d57e 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/prefix/BasicCompletionTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/prefix/BasicCompletionTest.java @@ -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); } } diff --git a/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/LRCompletionBasicTest.java b/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/LRCompletionBasicTest.java index b886d7d93f1..9d51fd58623 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/LRCompletionBasicTest.java +++ b/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/LRCompletionBasicTest.java @@ -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()); } + } diff --git a/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/LRCompletionParseTest.java b/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/LRCompletionParseTest.java index 1a46772fce3..f86ae83105a 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/LRCompletionParseTest.java +++ b/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/LRCompletionParseTest.java @@ -56,7 +56,7 @@ public class LRCompletionParseTest extends TestCase { }; - protected IBinding[] getBindings(IASTName[] names) { + public static IBinding[] getBindings(IASTName[] names) { List bindings = new ArrayList(); for(IASTName name : names) diff --git a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/cpp/CPPASTAmbiguousDeclarator.java b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/cpp/CPPASTAmbiguousDeclarator.java index 972665e459e..638a84c42ac 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/cpp/CPPASTAmbiguousDeclarator.java +++ b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/cpp/CPPASTAmbiguousDeclarator.java @@ -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); } diff --git a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/cpp/CPPBuildASTParserAction.java b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/cpp/CPPBuildASTParserAction.java index 86423d78650..0acea2842a8 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/cpp/CPPBuildASTParserAction.java +++ b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/cpp/CPPBuildASTParserAction.java @@ -1198,21 +1198,32 @@ public class CPPBuildASTParserAction extends BuildASTParserAction { List declarators = hasDeclaratorList ? astStack.closeScope() : Collections.emptyList(); IASTDeclSpecifier declSpecifier = (IASTDeclSpecifier) astStack.pop(); // may be null List 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) {