From dd0c8223c8f956dd1bc947aa21506d819b0bd963 Mon Sep 17 00:00:00 2001 From: Doug Schaefer Date: Wed, 20 Apr 2005 20:26:02 +0000 Subject: [PATCH] A half hearted attempt at completion inside a template id. --- .../tests/prefix/BasicCompletionTest.java | 62 +++++++++++------ .../dom/parser/cpp/GNUCPPSourceParser.java | 69 +++++++++++-------- 2 files changed, 83 insertions(+), 48 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 c91127b7460..1a15f7f151b 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 @@ -33,12 +33,35 @@ public class BasicCompletionTest extends CompletionTestBase { testVar(getGCCCompletionNode(code.toString())); } - private void testFunction(ASTCompletionNode node) throws Exception { + public void testFunction() throws Exception { + StringBuffer code = new StringBuffer(); + code.append("void func(int x) { }"); + code.append("void func2() { fu"); + + // C++ + ASTCompletionNode node = getGPPCompletionNode(code.toString()); 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].resolvePrefix(); + // There should be two since they both start with fu + assertEquals(2, bindings.length); + assertEquals("func", ((IFunction)bindings[0]).getName()); + assertEquals("func2", ((IFunction)bindings[1]).getName()); + // The second name shouldn't be hooked up + assertNull(names[1].getTranslationUnit()); + // The declaration should point to nothing since there are no types + bindings = names[2].resolvePrefix(); + assertEquals(0, bindings.length); + + // C + node = getGCCCompletionNode(code.toString()); + 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 - IBinding[] bindings = sortBindings(names[0].resolvePrefix()); + bindings = sortBindings(names[0].resolvePrefix()); // There should be two since they both start with fu assertEquals(2, bindings.length); assertEquals("func", ((IFunction)bindings[0]).getName()); @@ -47,29 +70,28 @@ public class BasicCompletionTest extends CompletionTestBase { bindings = names[1].resolvePrefix(); assertEquals(0, bindings.length); } - - public void testFunction() throws Exception { - StringBuffer code = new StringBuffer(); - code.append("void func(int x) { }"); - code.append("void func2() { fu"); - testFunction(getGPPCompletionNode(code.toString())); - testFunction(getGCCCompletionNode(code.toString())); - } - public void testTypedef(ASTCompletionNode node) { - IASTName[] names = node.getNames(); - assertEquals(1, names.length); - IBinding[] bindings = names[0].resolvePrefix(); - assertEquals(1, bindings.length); - assertEquals("blah", ((ITypedef)bindings[0]).getName()); - } - public void testTypedef() throws Exception { StringBuffer code = new StringBuffer(); code.append("typedef int blah;"); code.append("bl"); - testTypedef(getGPPCompletionNode(code.toString())); - testTypedef(getGCCCompletionNode(code.toString())); + + // C++ + ASTCompletionNode node = getGPPCompletionNode(code.toString()); + IASTName[] names = node.getNames(); + assertEquals(2, names.length); + assertNull(names[0].getTranslationUnit()); + IBinding[] bindings = names[1].resolvePrefix(); + assertEquals(1, bindings.length); + assertEquals("blah", ((ITypedef)bindings[0]).getName()); + + // C + node = getGCCCompletionNode(code.toString()); + names = node.getNames(); + assertEquals(1, names.length); + bindings = names[0].resolvePrefix(); + assertEquals(1, bindings.length); + assertEquals("blah", ((ITypedef)bindings[0]).getName()); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java index 8794c7092c8..aedc72057f7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java @@ -281,7 +281,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { templateIdScopes.push(IToken.tLT); - while (LT(1) != IToken.tGT) { + while (LT(1) != IToken.tGT && LT(1) != IToken.tEOC) { completedArg = false; IToken mark = mark(); @@ -308,7 +308,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { if (LT(1) == IToken.tCOMMA) { consume(); - } else if (LT(1) != IToken.tGT) { + } else if (LT(1) != IToken.tGT && LT(1) != IToken.tEOC) { failed = true; endOffset = LA(1).getEndOffset(); break; @@ -420,7 +420,14 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { try { List list = templateArgumentList(); argumentList.addSegment(list); - last = consume(IToken.tGT); + switch (LT(1)) { + case IToken.tGT: + case IToken.tEOC: + last = consume(); + break; + default: + throw backtrack; + } } catch (BacktrackException bt) { argumentList.addSegment(null); backup(secondMark); @@ -924,7 +931,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { try { declSpecifier = declSpecifierSeq(true, true); - declarator = declarator(SimpleDeclarationStrategy.TRY_CONSTRUCTOR, + if (LT(1) != IToken.tEOC) + declarator = declarator(SimpleDeclarationStrategy.TRY_CONSTRUCTOR, true, forNewExpression); } catch (BacktrackException bt) { backup(mark); @@ -932,27 +940,29 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { declarator) - startingOffset); } - if (declarator == null || declarator.getName().toString() != null) //$NON-NLS-1$ - { - backup(mark); - throwBacktrack(startingOffset, figureEndOffset(declSpecifier, - declarator) - - startingOffset); + if (declarator != null) { + if (declarator.getName().toString() != null) + { + backup(mark); + throwBacktrack(startingOffset, figureEndOffset(declSpecifier, + declarator) + - startingOffset); + } + if (declSpecifier instanceof IASTSimpleDeclSpecifier + && ((ASTNode) declSpecifier).getLength() == 0) { + backup(mark); + throwBacktrack(startingOffset, figureEndOffset(declSpecifier, + declarator) + - startingOffset); + } + if (declarator instanceof IASTArrayDeclarator && skipArrayModifiers) { + backup(mark); + throwBacktrack(startingOffset, figureEndOffset(declSpecifier, + declarator) + - startingOffset); + } } - if (declSpecifier instanceof IASTSimpleDeclSpecifier - && ((ASTNode) declSpecifier).getLength() == 0) { - backup(mark); - throwBacktrack(startingOffset, figureEndOffset(declSpecifier, - declarator) - - startingOffset); - } - if (declarator instanceof IASTArrayDeclarator && skipArrayModifiers) { - backup(mark); - throwBacktrack(startingOffset, figureEndOffset(declSpecifier, - declarator) - - startingOffset); - } - + IASTTypeId result = createTypeId(); ((ASTNode) result).setOffsetAndLength(startingOffset, figureEndOffset( declSpecifier, declarator) @@ -962,10 +972,12 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { declSpecifier.setParent(result); declSpecifier.setPropertyInParent(IASTTypeId.DECL_SPECIFIER); - result.setAbstractDeclarator(declarator); - declarator.setParent(result); - declarator.setPropertyInParent(IASTTypeId.ABSTRACT_DECLARATOR); - + if (declarator != null) { + result.setAbstractDeclarator(declarator); + declarator.setParent(result); + declarator.setPropertyInParent(IASTTypeId.ABSTRACT_DECLARATOR); + } + return result; } @@ -3290,6 +3302,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { break; case IToken.tCOLONCOLON: case IToken.tIDENTIFIER: + case IToken.tCOMPLETION: // TODO - Kludgy way to handle constructors/destructors if (flags.haveEncounteredRawType()) break declSpecifiers;