diff --git a/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/c99/C99CompleteParser2Tests.java b/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/c99/C99CompleteParser2Tests.java index f1c622010b5..90fecc50a9d 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/c99/C99CompleteParser2Tests.java +++ b/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/c99/C99CompleteParser2Tests.java @@ -62,13 +62,13 @@ public class C99CompleteParser2Tests extends CompleteParser2Tests { // fail(); // } catch(AssertionError _) { } // } -// -// -// public void testBug102376() throws Exception { // gcc extension -// try { -// super.testBug102376(); -// fail(); -// } catch(AssertionError _) { } -// } + + + public void testBug102376() throws Exception { // gcc extension + try { + super.testBug102376(); + fail(); + } catch(AssertionFailedError _) { } + } } diff --git a/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/c99/C99CompletionBasicTest.java b/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/c99/C99CompletionBasicTest.java index 5d9ab1467b3..83fbb71938a 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/c99/C99CompletionBasicTest.java +++ b/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/c99/C99CompletionBasicTest.java @@ -44,10 +44,6 @@ public class C99CompletionBasicTest extends BasicCompletionTest { return C99Language.getDefault(); } - // The C99 parser currently doesn't support ambiguity nodes. - // Therefore calling IASTCompletionNode.getNames() will - // never return more than one name. - @Override public void testFunction() throws Exception { @@ -60,9 +56,9 @@ public class C99CompletionBasicTest extends BasicCompletionTest { IASTName[] names = node.getNames(); // There is only one name, for now - assertEquals(1, names.length); + assertEquals(2, names.length); // The expression points to our functions - IBinding[] bindings = sortBindings(names[0].getCompletionContext().findBindings(names[0], true)); + 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$ diff --git a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/CPreprocessorAdapter.java b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/CPreprocessorAdapter.java index 987d7957dfb..12e7ba708b1 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/CPreprocessorAdapter.java +++ b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/CPreprocessorAdapter.java @@ -72,10 +72,8 @@ class CPreprocessorAdapter { org.eclipse.cdt.core.parser.IToken domEocToken = preprocessor.nextToken(); assert domEocToken.getType() == tEOC; - IToken eocToken = createEOCToken(domEocToken, tokenMap); - for(int i = 0; i < NUM_EOC_TOKENS; i++) - tokenCollector.addToken(eocToken); // reuse the same reference, no need to create several objects + tokenCollector.addToken(createEOCToken(domEocToken, tokenMap)); break; } diff --git a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/ASTCompletionNode.java b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/ASTCompletionNode.java index 50c6430a7ea..803d1341d5e 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/ASTCompletionNode.java +++ b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/ASTCompletionNode.java @@ -11,6 +11,7 @@ package org.eclipse.cdt.core.dom.lrparser.action; import java.util.LinkedList; +import java.util.List; import org.eclipse.cdt.core.dom.ast.IASTCompletionNode; import org.eclipse.cdt.core.dom.ast.IASTName; @@ -37,7 +38,7 @@ import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; */ public class ASTCompletionNode implements IASTCompletionNode { - private final LinkedList names = new LinkedList(); + private final List names = new LinkedList(); private final String prefix; private final IASTTranslationUnit tu; @@ -73,7 +74,7 @@ public class ASTCompletionNode implements IASTCompletionNode { public IASTName[] getNames() { - return names.toArray(new IASTName[0]); + return names.toArray(new IASTName[names.size()]); } diff --git a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/BuildASTParserAction.java b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/BuildASTParserAction.java index ad3cd0a8418..5138f59eecf 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/BuildASTParserAction.java +++ b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/BuildASTParserAction.java @@ -98,8 +98,8 @@ public abstract class BuildASTParserAction { // turn debug tracing on and off // TODO move this into an AspectJ project - protected static final boolean TRACE_ACTIONS = true; - protected static final boolean TRACE_AST_STACK = true; + protected static final boolean TRACE_ACTIONS = false; + protected static final boolean TRACE_AST_STACK = false; /** Stack that holds the intermediate nodes as the AST is being built */ @@ -163,6 +163,19 @@ public abstract class BuildASTParserAction { } + /** + * Used to combine completion nodes from secondary parsers into + * the main completion node. + */ + protected void addNameToCompletionNode(IASTCompletionNode node) { + if(node == null) + return; + + for(IASTName name : node.getNames()) + addNameToCompletionNode(name, node.getPrefix()); + } + + /** * Returns the completion node if this is a completion parse, null otherwise. */ @@ -469,7 +482,8 @@ public abstract class BuildASTParserAction { // try parsing as non-cast to resolve ambiguities C99NoCastExpressionParser alternateParser = new C99NoCastExpressionParser(C99Parsersym.orderedTerminalSymbols); alternateParser.setTokens(parser.getRuleTokens()); - alternateParser.parse(tu); + IASTCompletionNode compNode = alternateParser.parse(tu); + addNameToCompletionNode(compNode); IASTExpression alternateExpr = alternateParser.getParseResult(); if(alternateExpr == null || alternateExpr instanceof IASTProblemExpression) diff --git a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/c99/C99BuildASTParserAction.java b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/c99/C99BuildASTParserAction.java index f2bed3655b4..6fba094ae82 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/c99/C99BuildASTParserAction.java +++ b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/c99/C99BuildASTParserAction.java @@ -38,6 +38,7 @@ import java.util.List; import lpg.lpgjavaruntime.IToken; +import org.eclipse.cdt.core.dom.ast.IASTCompletionNode; import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; @@ -192,7 +193,8 @@ public class C99BuildASTParserAction extends BuildASTParserAction { // try parsing as an expression to resolve ambiguities C99SizeofExpressionParser alternateParser = new C99SizeofExpressionParser(C99Parsersym.orderedTerminalSymbols); alternateParser.setTokens(parser.getRuleTokens()); - alternateParser.parse(tu); + IASTCompletionNode completionNode = alternateParser.parse(tu); + addNameToCompletionNode(completionNode); IASTExpression alternateExpr = alternateParser.getParseResult(); if(alternateExpr == null || alternateExpr instanceof IASTProblemExpression) @@ -580,6 +582,14 @@ public class C99BuildASTParserAction extends BuildASTParserAction { public void consumeDeclarationEmpty() { if(TRACE_ACTIONS) DebugUtil.printMethodTrace(); + // Don't generate declaration nodes for extra EOC tokens + // TODO: the token type must be converted + if(asC99Kind(parser.getLeftIToken()) == C99Parsersym.TK_EndOfCompletion) + return; + + List tokens = parser.getRuleTokens(); + + System.out.println("what: " + parser.getLeftIToken().getKind()); IASTDeclSpecifier declSpecifier = nodeFactory.newCSimpleDeclSpecifier(); IASTSimpleDeclaration declaration = nodeFactory.newSimpleDeclaration(declSpecifier); setOffsetAndLength(declSpecifier); @@ -690,7 +700,8 @@ public class C99BuildASTParserAction extends BuildASTParserAction { C99ExpressionStatementParser expressionParser = new C99ExpressionStatementParser(C99Parsersym.orderedTerminalSymbols); expressionParser.setTokens(parser.getRuleTokens()); // need to pass tu because any completion nodes need to be linked directly to the root - expressionParser.parse(tu); + IASTCompletionNode compNode = expressionParser.parse(tu); + addNameToCompletionNode(compNode); IASTExpression expr = expressionParser.getParseResult(); if(expr != null && !(expr instanceof IASTProblemExpression)) { // the parse may fail @@ -699,10 +710,12 @@ public class C99BuildASTParserAction extends BuildASTParserAction { } } - if(expressionStatement == null) + if(expressionStatement == null) { astStack.push(declarationStatement); - else + } + else { astStack.push(nodeFactory.newAmbiguousStatement(declarationStatement, expressionStatement)); + } if(TRACE_AST_STACK) System.out.println(astStack);