From 85be18a5f9556c1b23f600ca12f088a1d51d3925 Mon Sep 17 00:00:00 2001 From: John Camelon Date: Mon, 14 Jun 2004 14:02:22 +0000 Subject: [PATCH] Partial fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=65610 --- .../core/parser/tests/QuickParseASTTests.java | 6 + .../cdt/core/parser/BacktrackException.java | 49 + .../core/parser/CompletionParser.java | 4 +- .../core/parser/ExpressionParser.java | 4422 ++++++++--------- .../cdt/internal/core/parser/Parser.java | 4087 ++++++++------- 5 files changed, 4179 insertions(+), 4389 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/QuickParseASTTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/QuickParseASTTests.java index 371a1654f35..cd7359d30fd 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/QuickParseASTTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/QuickParseASTTests.java @@ -2244,4 +2244,10 @@ public class QuickParseASTTests extends BaseASTTest assertFalse( iter.hasNext() ); } } + + public void testBadIdentifier() throws Exception + { + parse( "class 0302 { private: int stinks; };", true, false ); //$NON-NLS-1$ + + } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/BacktrackException.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/BacktrackException.java index 766edb3b0ec..7228d7c5c43 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/BacktrackException.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/BacktrackException.java @@ -16,4 +16,53 @@ package org.eclipse.cdt.core.parser; */ public class BacktrackException extends Exception { + + private IProblem problem; + private int startOffset; + private int endOffset; + + /** + * @param p + */ + public void initialize(IProblem p) { + reset(); + problem = p; + } + + /** + * + */ + private void reset() { + problem = null; + startOffset = 0; + endOffset = 0; + } + /** + * @return Returns the problem. + */ + public final IProblem getProblem() { + return problem; + } + + /** + * @param startingOffset + * @param endingOffset + */ + public void initialize(int startingOffset, int endingOffset) { + reset(); + startOffset = startingOffset; + endOffset = endingOffset; + } + /** + * @return Returns the offset. + */ + public final int getStartingOffset() { + return startOffset; + } + /** + * @return Returns the endOffset. + */ + public final int getEndOffset() { + return endOffset; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/CompletionParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/CompletionParser.java index 1aed8cb50b5..2b2a3a51718 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/CompletionParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/CompletionParser.java @@ -131,7 +131,9 @@ public class CompletionParser extends ContextualParser implements IParser { protected void catchHandlerSequence(IASTScope scope) throws EndOfFileException, BacktrackException { if( LT(1) != IToken.t_catch ) - throw backtrack; // error, need at least one of these + { + throwBacktrack(LA(1).getOffset()); // error, need at least one of these + } while (LT(1) == IToken.t_catch) { consume(IToken.t_catch); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ExpressionParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ExpressionParser.java index 1505e6ade0c..b8f862bc57d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ExpressionParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ExpressionParser.java @@ -18,6 +18,7 @@ import java.util.Stack; import org.eclipse.cdt.core.parser.BacktrackException; import org.eclipse.cdt.core.parser.EndOfFileException; import org.eclipse.cdt.core.parser.IParserLogService; +import org.eclipse.cdt.core.parser.IProblem; import org.eclipse.cdt.core.parser.IScanner; import org.eclipse.cdt.core.parser.IToken; import org.eclipse.cdt.core.parser.ITokenDuple; @@ -52,10 +53,27 @@ public class ExpressionParser implements IExpressionParser, IParserData { protected static final String EMPTY_STRING = ""; //$NON-NLS-1$ private static int FIRST_ERROR_OFFSET_UNSET = -1; protected boolean parsePassed = true; - protected int firstErrorOffset = FIRST_ERROR_OFFSET_UNSET; - protected static BacktrackException backtrack = new BacktrackException(); + protected int firstErrorOffset = FIRST_ERROR_OFFSET_UNSET; + private BacktrackException backtrack = new BacktrackException(); + private int backtrackCount = 0; + + protected final void throwBacktrack( IProblem problem ) throws BacktrackException { + ++backtrackCount; + backtrack.initialize( problem ); + throw backtrack; + } + + protected final void throwBacktrack( int startingOffset ) throws BacktrackException { + ++backtrackCount; + if( lastToken != null ) + backtrack.initialize( startingOffset, lastToken.getEndOffset() ); + else + backtrack.initialize( startingOffset, startingOffset ); + throw backtrack; + } + protected final IParserExtension extension; - + //TODO this stuff needs to be encapsulated by IParserData protected final IParserLogService log; protected ParserLanguage language = ParserLanguage.CPP; @@ -66,7 +84,7 @@ public class ExpressionParser implements IExpressionParser, IParserData { private boolean limitReached = false; private Stack templateIdScopes = null; private TypeId typeIdInstance = new TypeId(); - + /** * @return Returns the astFactory. */ @@ -80,7 +98,6 @@ public class ExpressionParser implements IExpressionParser, IParserData { return log; } - /** * Look Ahead in the token list to see what is coming. * @@ -89,23 +106,22 @@ public class ExpressionParser implements IExpressionParser, IParserData { * @throws EndOfFileException if looking ahead encounters EOF, throw EndOfFile */ public IToken LA(int i) throws EndOfFileException { - - if (parserTimeout()){ - throw new ParseError( ParseError.ParseErrorKind.TIMEOUT ); - } - - if (i < 1) // can't go backwards - return null; - if (currToken == null) - currToken = fetchToken(); - IToken retToken = currToken; - for (; i > 1; --i) - { - retToken = retToken.getNext(); - if (retToken == null) - retToken = fetchToken(); - } - return retToken; + + if (parserTimeout()) { + throw new ParseError(ParseError.ParseErrorKind.TIMEOUT); + } + + if (i < 1) // can't go backwards + return null; + if (currToken == null) + currToken = fetchToken(); + IToken retToken = currToken; + for (; i > 1; --i) { + retToken = retToken.getNext(); + if (retToken == null) + retToken = fetchToken(); + } + return retToken; } /** @@ -116,7 +132,7 @@ public class ExpressionParser implements IExpressionParser, IParserData { * @throws EndOfFileException if looking ahead encounters EOF, throw EndOfFile */ public int LT(int i) throws EndOfFileException { - return LA(i).getType(); + return LA(i).getType(); } /** @@ -126,14 +142,14 @@ public class ExpressionParser implements IExpressionParser, IParserData { * @throws EndOfFileException If there is no token to consume. */ public IToken consume() throws EndOfFileException { - - if (currToken == null) - currToken = fetchToken(); - if (currToken != null) - lastToken = currToken; - currToken = currToken.getNext(); - handleNewToken( lastToken ); - return lastToken; + + if (currToken == null) + currToken = fetchToken(); + if (currToken != null) + lastToken = currToken; + currToken = currToken.getNext(); + handleNewToken(lastToken); + return lastToken; } /** @@ -143,10 +159,12 @@ public class ExpressionParser implements IExpressionParser, IParserData { * @return the token that was consumed and removed from our buffer. * @throws BacktrackException If LT(1) != type */ - public IToken consume(int type) throws EndOfFileException, BacktrackException { - if (LT(1) == type) - return consume(); - throw backtrack; + public IToken consume(int type) throws EndOfFileException, + BacktrackException { + if (LT(1) == type) + return consume(); + throwBacktrack(LA(1).getOffset()); + return null; } /** @@ -156,9 +174,9 @@ public class ExpressionParser implements IExpressionParser, IParserData { * @throws EndOfFileException If there are no more tokens. */ public IToken mark() throws EndOfFileException { - if (currToken == null) - currToken = fetchToken(); - return currToken; + if (currToken == null) + currToken = fetchToken(); + return currToken; } /** @@ -168,12 +186,9 @@ public class ExpressionParser implements IExpressionParser, IParserData { * */ public void backup(IToken mark) { - currToken = mark; - lastToken = null; // this is not entirely right ... + currToken = mark; + lastToken = null; // this is not entirely right ... } - - - /** * @param extension TODO @@ -182,9 +197,10 @@ public class ExpressionParser implements IExpressionParser, IParserData { * @param language2 * @param log2 */ - public ExpressionParser(IScanner scanner, ParserLanguage language, IParserLogService log, IParserExtension extension) { + public ExpressionParser(IScanner scanner, ParserLanguage language, + IParserLogService log, IParserExtension extension) { this.scanner = scanner; - this.language = language; + this.language = language; this.log = log; this.extension = extension; setupASTFactory(scanner, language); @@ -195,7 +211,8 @@ public class ExpressionParser implements IExpressionParser, IParserData { * @param language */ protected void setupASTFactory(IScanner scanner, ParserLanguage language) { - astFactory = ParserFactory.createASTFactory( this, ParserMode.EXPRESSION_PARSE, language); + astFactory = ParserFactory.createASTFactory(this, + ParserMode.EXPRESSION_PARSE, language); scanner.setASTFactory(astFactory); astFactory.setLogger(log); } @@ -207,17 +224,13 @@ public class ExpressionParser implements IExpressionParser, IParserData { * @throws EndOfFileException */ protected void failParse() { - try - { - if (firstErrorOffset == FIRST_ERROR_OFFSET_UNSET ) - firstErrorOffset = LA(1).getOffset(); - } catch( EndOfFileException eof ) - { + try { + if (firstErrorOffset == FIRST_ERROR_OFFSET_UNSET) + firstErrorOffset = LA(1).getOffset(); + } catch (EndOfFileException eof) { // do nothing - } - finally - { - parsePassed = false; + } finally { + parsePassed = false; } } @@ -228,137 +241,149 @@ public class ExpressionParser implements IExpressionParser, IParserData { * @return Last consumed token, or previousLast if nothing was consumed * @throws BacktrackException request a backtrack */ - protected IToken consumeTemplateParameters(IToken previousLast) throws EndOfFileException, BacktrackException { - if( language != ParserLanguage.CPP ) return previousLast; - IToken last = previousLast; - if (LT(1) == IToken.tLT) - { - last = consume(IToken.tLT); - // until we get all the names sorted out - Stack scopes = new Stack(); - scopes.push(new Integer(IToken.tLT)); - - while (!scopes.empty()) - { + protected IToken consumeTemplateParameters(IToken previousLast) + throws EndOfFileException, BacktrackException { + if (language != ParserLanguage.CPP) + return previousLast; + int startingOffset = previousLast == null ? lastToken.getOffset() : previousLast.getOffset(); + IToken last = previousLast; + if (LT(1) == IToken.tLT) { + last = consume(IToken.tLT); + // until we get all the names sorted out + Stack scopes = new Stack(); + scopes.push(new Integer(IToken.tLT)); + + while (!scopes.empty()) { int top; - last = consume(); - - switch (last.getType()) { - case IToken.tGT : - if (((Integer)scopes.peek()).intValue() == IToken.tLT) { + last = consume(); + + switch (last.getType()) { + case IToken.tGT : + if (((Integer) scopes.peek()).intValue() == IToken.tLT) { scopes.pop(); } - break; + break; case IToken.tRBRACKET : do { - top = ((Integer)scopes.pop()).intValue(); - } while (!scopes.empty() && (top == IToken.tGT || top == IToken.tLT)); - if (top != IToken.tLBRACKET) throw backtrack; - + top = ((Integer) scopes.pop()).intValue(); + } while (!scopes.empty() + && (top == IToken.tGT || top == IToken.tLT)); + if (top != IToken.tLBRACKET) + throwBacktrack(startingOffset ); + break; case IToken.tRPAREN : do { - top = ((Integer)scopes.pop()).intValue(); - } while (!scopes.empty() && (top == IToken.tGT || top == IToken.tLT)); - if (top != IToken.tLPAREN) throw backtrack; - + top = ((Integer) scopes.pop()).intValue(); + } while (!scopes.empty() + && (top == IToken.tGT || top == IToken.tLT)); + if (top != IToken.tLPAREN) + throwBacktrack(startingOffset); + break; - case IToken.tLT : - case IToken.tLBRACKET: - case IToken.tLPAREN: + case IToken.tLT : + case IToken.tLBRACKET : + case IToken.tLPAREN : scopes.push(new Integer(last.getType())); - break; - } - } - } - return last; + break; + } + } + } + return last; } - protected List templateArgumentList( IASTScope scope, IASTCompletionNode.CompletionKind kind ) throws EndOfFileException, BacktrackException - { - IASTExpression expression = null; - List list = new LinkedList(); - - boolean completedArg = false; - boolean failed = false; - - if( templateIdScopes == null ){ - templateIdScopes = new Stack(); - } - templateIdScopes.push( new Integer( IToken.tLT ) ); - - while( LT(1) != IToken.tGT ){ - completedArg = false; - - IToken mark = mark(); - - try{ - IASTTypeId typeId = typeId( scope, false, kind ); - - expression = astFactory.createExpression( scope, IASTExpression.Kind.POSTFIX_TYPEID_TYPEID, - null, null, null, typeId, null, EMPTY_STRING, null); - list.add( expression ); - completedArg = true; - } catch( BacktrackException e ){ - backup( mark ); - } catch (ASTSemanticException e) { - backup( mark ); + protected List templateArgumentList(IASTScope scope, + IASTCompletionNode.CompletionKind kind) throws EndOfFileException, + BacktrackException { + int startingOffset = LA(1).getOffset(); + IASTExpression expression = null; + List list = new LinkedList(); + + boolean completedArg = false; + boolean failed = false; + + if (templateIdScopes == null) { + templateIdScopes = new Stack(); + } + templateIdScopes.push(new Integer(IToken.tLT)); + + while (LT(1) != IToken.tGT) { + completedArg = false; + + IToken mark = mark(); + + try { + IASTTypeId typeId = typeId(scope, false, kind); + + expression = astFactory.createExpression(scope, + IASTExpression.Kind.POSTFIX_TYPEID_TYPEID, null, null, + null, typeId, null, EMPTY_STRING, null); + list.add(expression); + completedArg = true; + } catch (BacktrackException e) { + backup(mark); + } catch (ASTSemanticException e) { + backup(mark); } - if( ! completedArg ){ - try{ - expression = assignmentExpression( scope, CompletionKind.VARIABLE_TYPE, KeywordSetKey.EXPRESSION ); - if( expression.getExpressionKind() == IASTExpression.Kind.PRIMARY_EMPTY ){ - throw backtrack; - } - list.add( expression ); - completedArg = true; - } catch( BacktrackException e ){ - backup( mark ); - } - } - if( !completedArg ){ - try{ - ITokenDuple nameDuple = name( scope, null, KeywordSetKey.EMPTY ); - expression = astFactory.createExpression( scope, IASTExpression.Kind.ID_EXPRESSION, - null, null, null, null, nameDuple, EMPTY_STRING, null); - list.add( expression ); - continue; - } catch( ASTSemanticException e ){ - failed = true; - break; - }catch( BacktrackException e ){ - failed = true; - break; - }catch( Exception e ){ - logException( "templateArgumentList::createExpression()", e ); //$NON-NLS-1$ - failed = true; - break; - } - } - - if( LT(1) == IToken.tCOMMA ){ - consume(); - } else if( LT(1) != IToken.tGT ){ - failed = true; - break; - } - } - - templateIdScopes.pop(); - if( templateIdScopes.size() == 0 ){ - templateIdScopes = null; - } - - if( failed ) { - if( expression != null ) - expression.freeReferences(astFactory.getReferenceManager()); - throw backtrack; - } - - return list; + if (!completedArg) { + try { + expression = assignmentExpression(scope, + CompletionKind.VARIABLE_TYPE, + KeywordSetKey.EXPRESSION); + if (expression.getExpressionKind() == IASTExpression.Kind.PRIMARY_EMPTY) { + throwBacktrack(startingOffset); + } + list.add(expression); + completedArg = true; + } catch (BacktrackException e) { + backup(mark); + } + } + if (!completedArg) { + try { + ITokenDuple nameDuple = name(scope, null, + KeywordSetKey.EMPTY); + expression = astFactory.createExpression(scope, + IASTExpression.Kind.ID_EXPRESSION, null, null, + null, null, nameDuple, EMPTY_STRING, null); + list.add(expression); + continue; + } catch (ASTSemanticException e) { + failed = true; + break; + } catch (BacktrackException e) { + failed = true; + break; + } catch (Exception e) { + logException("templateArgumentList::createExpression()", e); //$NON-NLS-1$ + failed = true; + break; + } + } + + if (LT(1) == IToken.tCOMMA) { + consume(); + } else if (LT(1) != IToken.tGT) { + failed = true; + break; + } + } + + templateIdScopes.pop(); + if (templateIdScopes.size() == 0) { + templateIdScopes = null; + } + + if (failed) { + if (expression != null) + expression.freeReferences(astFactory.getReferenceManager()); + throwBacktrack(startingOffset); + } + + return list; } - + /** * Parse a template-id, according to the ANSI C++ spec. * @@ -369,10 +394,11 @@ public class ExpressionParser implements IExpressionParser, IParserData { * * @throws BacktrackException request a backtrack */ - protected IToken templateId(IASTScope scope, CompletionKind kind) throws EndOfFileException, BacktrackException { - ITokenDuple duple = name(scope, kind, KeywordSetKey.EMPTY ); - //IToken last = consumeTemplateParameters(duple.getLastToken()); - return duple.getLastToken();//last; + protected IToken templateId(IASTScope scope, CompletionKind kind) + throws EndOfFileException, BacktrackException { + ITokenDuple duple = name(scope, kind, KeywordSetKey.EMPTY); + //IToken last = consumeTemplateParameters(duple.getLastToken()); + return duple.getLastToken();//last; } /** @@ -388,86 +414,91 @@ public class ExpressionParser implements IExpressionParser, IParserData { * @param key TODO * @throws BacktrackException request a backtrack */ - protected ITokenDuple name(IASTScope scope, IASTCompletionNode.CompletionKind kind, KeywordSetKey key ) throws BacktrackException, EndOfFileException { - - TemplateParameterManager argumentList = TemplateParameterManager.getInstance(); - - try - { - IToken first = LA(1); - IToken last = null; - IToken mark = mark(); - - - boolean hasTemplateId = false; - boolean startsWithColonColon = false; - - if (LT(1) == IToken.tCOLONCOLON){ - argumentList.addSegment( null ); - last = consume( IToken.tCOLONCOLON ); - setCompletionValues( scope, kind, KeywordSetKey.EMPTY, getCompliationUnit() ); - startsWithColonColon = true; - } - - if (LT(1) == IToken.tCOMPL) - consume(); - - switch (LT(1)) - { - case IToken.tIDENTIFIER : - IToken prev = last; - last = consume(IToken.tIDENTIFIER); - if( startsWithColonColon ) - setCompletionValues( scope, kind, getCompliationUnit() ); - else if( prev != null ) - setCompletionValues(scope, kind, first, prev, KeywordSetKey.EMPTY ); - else - setCompletionValuesNoContext(scope, kind, key ); - - last = consumeTemplateArguments(scope, last, argumentList, kind); - if( last.getType() == IToken.tGT ) - hasTemplateId = true; - break; - - default : - backup(mark); - throw backtrack; - } - - while (LT(1) == IToken.tCOLONCOLON) - { - IToken prev = last; - last = consume(IToken.tCOLONCOLON); - setCompletionValues( scope, kind, first, prev, KeywordSetKey.EMPTY ); - - if (queryLookaheadCapability() && LT(1) == IToken.t_template) - consume(); - - if (queryLookaheadCapability() && LT(1) == IToken.tCOMPL) - consume(); - - switch (LT(1)) - { - case IToken.t_operator : - backup(mark); - throw backtrack; - case IToken.tIDENTIFIER : - prev = last; - last = consume(); - setCompletionValues( scope, kind, first, prev, KeywordSetKey.EMPTY ); - last = consumeTemplateArguments(scope, last, argumentList, kind); - if( last.getType() == IToken.tGT ) - hasTemplateId = true; - } - } - - ITokenDuple tokenDuple = TokenFactory.createTokenDuple(first, last, ( hasTemplateId ? argumentList.getTemplateArgumentsList() : null ) ); - setGreaterNameContext( tokenDuple ); + protected ITokenDuple name(IASTScope scope, + IASTCompletionNode.CompletionKind kind, KeywordSetKey key) + throws BacktrackException, EndOfFileException { + + TemplateParameterManager argumentList = TemplateParameterManager + .getInstance(); + + try { + IToken first = LA(1); + IToken last = null; + IToken mark = mark(); + + boolean hasTemplateId = false; + boolean startsWithColonColon = false; + + if (LT(1) == IToken.tCOLONCOLON) { + argumentList.addSegment(null); + last = consume(IToken.tCOLONCOLON); + setCompletionValues(scope, kind, KeywordSetKey.EMPTY, + getCompliationUnit()); + startsWithColonColon = true; + } + + if (LT(1) == IToken.tCOMPL) + consume(); + + switch (LT(1)) { + case IToken.tIDENTIFIER : + IToken prev = last; + last = consume(IToken.tIDENTIFIER); + if (startsWithColonColon) + setCompletionValues(scope, kind, getCompliationUnit()); + else if (prev != null) + setCompletionValues(scope, kind, first, prev, + KeywordSetKey.EMPTY); + else + setCompletionValuesNoContext(scope, kind, key); + + last = consumeTemplateArguments(scope, last, argumentList, + kind); + if (last.getType() == IToken.tGT) + hasTemplateId = true; + break; + + default : + backup(mark); + throwBacktrack(first.getOffset()); + } + + while (LT(1) == IToken.tCOLONCOLON) { + IToken prev = last; + last = consume(IToken.tCOLONCOLON); + setCompletionValues(scope, kind, first, prev, + KeywordSetKey.EMPTY); + + if (queryLookaheadCapability() && LT(1) == IToken.t_template) + consume(); + + if (queryLookaheadCapability() && LT(1) == IToken.tCOMPL) + consume(); + + switch (LT(1)) { + case IToken.t_operator : + backup(mark); + throwBacktrack(first.getOffset()); + case IToken.tIDENTIFIER : + prev = last; + last = consume(); + setCompletionValues(scope, kind, first, prev, + KeywordSetKey.EMPTY); + last = consumeTemplateArguments(scope, last, + argumentList, kind); + if (last.getType() == IToken.tGT) + hasTemplateId = true; + } + } + + ITokenDuple tokenDuple = TokenFactory.createTokenDuple(first, last, + (hasTemplateId + ? argumentList.getTemplateArgumentsList() + : null)); + setGreaterNameContext(tokenDuple); return tokenDuple; - } - finally - { - TemplateParameterManager.returnInstance( argumentList ); + } finally { + TemplateParameterManager.returnInstance(argumentList); } } @@ -477,7 +508,8 @@ public class ExpressionParser implements IExpressionParser, IParserData { * @param kind * @param key */ - protected void setCompletionValuesNoContext(IASTScope scope, CompletionKind kind, KeywordSetKey key) throws EndOfFileException { + protected void setCompletionValuesNoContext(IASTScope scope, + CompletionKind kind, KeywordSetKey key) throws EndOfFileException { } /** * @param tokenDuple @@ -490,14 +522,16 @@ public class ExpressionParser implements IExpressionParser, IParserData { * @param scope * @param kind */ - protected void setCompletionValues(IASTScope scope, CompletionKind kind, IASTNode context ) throws EndOfFileException{ + protected void setCompletionValues(IASTScope scope, CompletionKind kind, + IASTNode context) throws EndOfFileException { } - + /** * @param scope * @param kind */ - protected void setCompletionValues(IASTScope scope, CompletionKind kind) throws EndOfFileException{ + protected void setCompletionValues(IASTScope scope, CompletionKind kind) + throws EndOfFileException { } /** @@ -513,8 +547,8 @@ public class ExpressionParser implements IExpressionParser, IParserData { * @param key * @param node */ - protected void setCompletionValues(IASTScope scope, CompletionKind kind, KeywordSetKey key, IASTNode node) throws EndOfFileException - { + protected void setCompletionValues(IASTScope scope, CompletionKind kind, + KeywordSetKey key, IASTNode node) throws EndOfFileException { } /** @@ -525,23 +559,25 @@ public class ExpressionParser implements IExpressionParser, IParserData { * @throws EndOfFileException * @throws BacktrackException */ - protected IToken consumeTemplateArguments(IASTScope scope, IToken last, TemplateParameterManager argumentList, IASTCompletionNode.CompletionKind completionKind) throws EndOfFileException, BacktrackException { - if( language != ParserLanguage.CPP ) return last; - if( LT(1) == IToken.tLT ){ + protected IToken consumeTemplateArguments(IASTScope scope, IToken last, + TemplateParameterManager argumentList, + IASTCompletionNode.CompletionKind completionKind) + throws EndOfFileException, BacktrackException { + if (language != ParserLanguage.CPP) + return last; + if (LT(1) == IToken.tLT) { IToken secondMark = mark(); - consume( IToken.tLT ); - try - { - List list = templateArgumentList( scope, completionKind ); - argumentList.addSegment( list ); - last = consume( IToken.tGT ); - } catch( BacktrackException bt ) - { - argumentList.addSegment( null ); - backup( secondMark ); - } + consume(IToken.tLT); + try { + List list = templateArgumentList(scope, completionKind); + argumentList.addSegment(list); + last = consume(IToken.tGT); + } catch (BacktrackException bt) { + argumentList.addSegment(null); + backup(secondMark); + } } else { - argumentList.addSegment( null ); + argumentList.addSegment(null); } return last; } @@ -557,133 +593,125 @@ public class ExpressionParser implements IExpressionParser, IParserData { * @return Returns the same object sent in. * @throws BacktrackException */ - protected IToken cvQualifier(IDeclarator declarator) throws EndOfFileException, BacktrackException { - IToken result = null; - switch (LT(1)) - { - case IToken.t_const : - result = consume( IToken.t_const ); - declarator.addPointerOperator(ASTPointerOperator.CONST_POINTER); - break; - case IToken.t_volatile : - result = consume( IToken.t_volatile ); - declarator.addPointerOperator(ASTPointerOperator.VOLATILE_POINTER); - break; - case IToken.t_restrict : - if( language == ParserLanguage.C ) - { - result = consume( IToken.t_restrict ); - declarator.addPointerOperator(ASTPointerOperator.RESTRICT_POINTER); + protected IToken cvQualifier(IDeclarator declarator) + throws EndOfFileException, BacktrackException { + IToken result = null; + int startingOffset = LA(1).getOffset(); + switch (LT(1)) { + case IToken.t_const : + result = consume(IToken.t_const); + declarator.addPointerOperator(ASTPointerOperator.CONST_POINTER); + break; + case IToken.t_volatile : + result = consume(IToken.t_volatile); + declarator + .addPointerOperator(ASTPointerOperator.VOLATILE_POINTER); + break; + case IToken.t_restrict : + if (language == ParserLanguage.C) { + result = consume(IToken.t_restrict); + declarator + .addPointerOperator(ASTPointerOperator.RESTRICT_POINTER); break; - } - if( extension.isValidCVModifier( language, IToken.t_restrict )) - { - result = consume( IToken.t_restrict ); - declarator.addPointerOperator( extension.getPointerOperator(language, IToken.t_restrict )); - break; - } - throw backtrack; + } + if (extension.isValidCVModifier(language, IToken.t_restrict)) { + result = consume(IToken.t_restrict); + declarator.addPointerOperator(extension.getPointerOperator( + language, IToken.t_restrict)); + break; + } + throwBacktrack(startingOffset); - - default : - if( extension.isValidCVModifier( language, LT(1))) - { - result = consume(); - declarator.addPointerOperator( extension.getPointerOperator( language, result.getType() )); - } - } - return result; - } - - protected void consumeArrayModifiers(IDeclarator d, IASTScope scope) throws EndOfFileException, BacktrackException { - while (LT(1) == IToken.tLBRACKET) - { - consume( IToken.tLBRACKET ); // eat the '[' - - IASTExpression exp = null; - if (LT(1) != IToken.tRBRACKET) - { - exp = constantExpression(scope, CompletionKind.SINGLE_NAME_REFERENCE, KeywordSetKey.EXPRESSION ); - } - consume(IToken.tRBRACKET); - IASTArrayModifier arrayMod; - try - { - arrayMod = astFactory.createArrayModifier(exp); - } - catch (Exception e) - { - logException( "consumeArrayModifiers::createArrayModifier()", e ); //$NON-NLS-1$ - throw backtrack; - } - d.addArrayModifier(arrayMod); - } - } - - protected void operatorId(Declarator d, IToken originalToken, TemplateParameterManager templateArgs, IASTCompletionNode.CompletionKind completionKind ) throws BacktrackException, EndOfFileException { - // we know this is an operator - IToken operatorToken = consume(IToken.t_operator); - IToken toSend = null; - if (LA(1).isOperator() - || LT(1) == IToken.tLPAREN - || LT(1) == IToken.tLBRACKET) - { - if ((LT(1) == IToken.t_new || LT(1) == IToken.t_delete) - && LT(2) == IToken.tLBRACKET - && LT(3) == IToken.tRBRACKET) - { - consume(); - consume(IToken.tLBRACKET); - toSend = consume(IToken.tRBRACKET); - // vector new and delete operators - } - else if (LT(1) == IToken.tLPAREN && LT(2) == IToken.tRPAREN) - { - // operator () - consume(IToken.tLPAREN); - toSend = consume(IToken.tRPAREN); - } - else if (LT(1) == IToken.tLBRACKET && LT(2) == IToken.tRBRACKET) - { - consume(IToken.tLBRACKET); - toSend = consume(IToken.tRBRACKET); - } - else if (LA(1).isOperator()) - toSend = consume(); - else - throw backtrack; - } - else - { - // must be a conversion function - typeId(d.getDeclarationWrapper().getScope(), true, CompletionKind.TYPE_REFERENCE ); - toSend = lastToken; - } - - boolean hasTemplateId = ( templateArgs != null ); - boolean grabbedNewInstance = false; - if( templateArgs == null ) - { - templateArgs = TemplateParameterManager.getInstance(); - grabbedNewInstance = true; - } - - try - { - toSend = consumeTemplateArguments( d.getDeclarationWrapper().getScope(), toSend, templateArgs, completionKind ); - if( toSend.getType() == IToken.tGT ){ - hasTemplateId = true; - } - - ITokenDuple duple = - TokenFactory.createTokenDuple( originalToken == null ? operatorToken : originalToken, toSend, (hasTemplateId ? templateArgs.getTemplateArgumentsList() : null ) ); - - d.setName(duple); + default : + if (extension.isValidCVModifier(language, LT(1))) { + result = consume(); + declarator.addPointerOperator(extension.getPointerOperator( + language, result.getType())); + } } - finally - { - if( grabbedNewInstance ) - TemplateParameterManager.returnInstance( templateArgs ); + return result; + } + + protected void consumeArrayModifiers(IDeclarator d, IASTScope scope) + throws EndOfFileException, BacktrackException { + int startingOffset = LA(1).getOffset(); + while (LT(1) == IToken.tLBRACKET) { + consume(IToken.tLBRACKET); // eat the '[' + + IASTExpression exp = null; + if (LT(1) != IToken.tRBRACKET) { + exp = constantExpression(scope, + CompletionKind.SINGLE_NAME_REFERENCE, + KeywordSetKey.EXPRESSION); + } + consume(IToken.tRBRACKET); + IASTArrayModifier arrayMod = null; + try { + arrayMod = astFactory.createArrayModifier(exp); + } catch (Exception e) { + logException("consumeArrayModifiers::createArrayModifier()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + d.addArrayModifier(arrayMod); + } + } + + protected void operatorId(Declarator d, IToken originalToken, + TemplateParameterManager templateArgs, + IASTCompletionNode.CompletionKind completionKind) + throws BacktrackException, EndOfFileException { + // we know this is an operator + IToken operatorToken = consume(IToken.t_operator); + IToken toSend = null; + if (LA(1).isOperator() || LT(1) == IToken.tLPAREN + || LT(1) == IToken.tLBRACKET) { + if ((LT(1) == IToken.t_new || LT(1) == IToken.t_delete) + && LT(2) == IToken.tLBRACKET && LT(3) == IToken.tRBRACKET) { + consume(); + consume(IToken.tLBRACKET); + toSend = consume(IToken.tRBRACKET); + // vector new and delete operators + } else if (LT(1) == IToken.tLPAREN && LT(2) == IToken.tRPAREN) { + // operator () + consume(IToken.tLPAREN); + toSend = consume(IToken.tRPAREN); + } else if (LT(1) == IToken.tLBRACKET && LT(2) == IToken.tRBRACKET) { + consume(IToken.tLBRACKET); + toSend = consume(IToken.tRBRACKET); + } else if (LA(1).isOperator()) + toSend = consume(); + else + throwBacktrack(operatorToken.getOffset()); + } else { + // must be a conversion function + typeId(d.getDeclarationWrapper().getScope(), true, + CompletionKind.TYPE_REFERENCE); + toSend = lastToken; + } + + boolean hasTemplateId = (templateArgs != null); + boolean grabbedNewInstance = false; + if (templateArgs == null) { + templateArgs = TemplateParameterManager.getInstance(); + grabbedNewInstance = true; + } + + try { + toSend = consumeTemplateArguments(d.getDeclarationWrapper() + .getScope(), toSend, templateArgs, completionKind); + if (toSend.getType() == IToken.tGT) { + hasTemplateId = true; + } + + ITokenDuple duple = TokenFactory.createTokenDuple( + originalToken == null ? operatorToken : originalToken, + toSend, (hasTemplateId ? templateArgs + .getTemplateArgumentsList() : null)); + + d.setName(duple); + } finally { + if (grabbedNewInstance) + TemplateParameterManager.returnInstance(templateArgs); } } @@ -698,65 +726,58 @@ public class ExpressionParser implements IExpressionParser, IParserData { * @param owner Declarator that this pointer operator corresponds to. * @throws BacktrackException request a backtrack */ - protected IToken consumePointerOperators(IDeclarator d) throws EndOfFileException, BacktrackException { + protected IToken consumePointerOperators(IDeclarator d) + throws EndOfFileException, BacktrackException { IToken result = null; - for( ; ; ) - { - if (LT(1) == IToken.tAMPER) - { - result = consume( IToken.tAMPER ); - d.addPointerOperator(ASTPointerOperator.REFERENCE); - return result; - - } - IToken mark = mark(); - - ITokenDuple nameDuple = null; - if (LT(1) == IToken.tIDENTIFIER || LT(1) == IToken.tCOLONCOLON) - { - try - { - try - { - nameDuple = name(d.getScope(), CompletionKind.SINGLE_NAME_REFERENCE, KeywordSetKey.EMPTY ); + for (;;) { + if (LT(1) == IToken.tAMPER) { + result = consume(IToken.tAMPER); + d.addPointerOperator(ASTPointerOperator.REFERENCE); + return result; + + } + IToken mark = mark(); + + ITokenDuple nameDuple = null; + if (LT(1) == IToken.tIDENTIFIER || LT(1) == IToken.tCOLONCOLON) { + try { + try { + nameDuple = name(d.getScope(), + CompletionKind.SINGLE_NAME_REFERENCE, + KeywordSetKey.EMPTY); + } catch (OffsetLimitReachedException olre) { + backup(mark); + return null; } - catch( OffsetLimitReachedException olre ) - { - backup( mark ); - return null; - } - } - catch( BacktrackException bt ) - { - backup( mark ); - return null; - } - } - if ( LT(1) == IToken.tSTAR) - { - result = consume(IToken.tSTAR); - - d.setPointerOperatorName(nameDuple); - - IToken successful = null; - for (;;) - { - IToken newSuccess = cvQualifier(d); - if( newSuccess != null ) successful = newSuccess; - else break; - - } - - if( successful == null ) - { - d.addPointerOperator( ASTPointerOperator.POINTER ); + } catch (BacktrackException bt) { + backup(mark); + return null; } - continue; - } - if( nameDuple != null ) - nameDuple.freeReferences( astFactory.getReferenceManager() ); - backup(mark); - return result; + } + if (LT(1) == IToken.tSTAR) { + result = consume(IToken.tSTAR); + + d.setPointerOperatorName(nameDuple); + + IToken successful = null; + for (;;) { + IToken newSuccess = cvQualifier(d); + if (newSuccess != null) + successful = newSuccess; + else + break; + + } + + if (successful == null) { + d.addPointerOperator(ASTPointerOperator.POINTER); + } + continue; + } + if (nameDuple != null) + nameDuple.freeReferences(astFactory.getReferenceManager()); + backup(mark); + return result; } } @@ -764,118 +785,106 @@ public class ExpressionParser implements IExpressionParser, IParserData { * @param expression * @throws BacktrackException */ - protected IASTExpression constantExpression(IASTScope scope, CompletionKind kind, KeywordSetKey key) throws BacktrackException, EndOfFileException { - return conditionalExpression(scope,kind,key); + protected IASTExpression constantExpression(IASTScope scope, + CompletionKind kind, KeywordSetKey key) throws BacktrackException, + EndOfFileException { + return conditionalExpression(scope, kind, key); } - public IASTExpression expression(IASTScope scope, CompletionKind kind, KeywordSetKey key) throws BacktrackException, EndOfFileException { - IASTExpression assignmentExpression = assignmentExpression(scope,kind,key); - while (LT(1) == IToken.tCOMMA) - { - consume(IToken.tCOMMA); - setParameterListExpression( assignmentExpression ); - IASTExpression secondExpression = assignmentExpression(scope,kind,key); - setParameterListExpression( null ); - try - { - assignmentExpression = - astFactory.createExpression( - scope, - IASTExpression.Kind.EXPRESSIONLIST, - assignmentExpression, - secondExpression, - null, - null, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e) - { - throw backtrack; - } catch (Exception e) - { - logException( "expression::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - } - return assignmentExpression; + public IASTExpression expression(IASTScope scope, CompletionKind kind, + KeywordSetKey key) throws BacktrackException, EndOfFileException { + int startingOffset = LA(1).getOffset(); + IASTExpression assignmentExpression = assignmentExpression(scope, kind, + key); + while (LT(1) == IToken.tCOMMA) { + consume(IToken.tCOMMA); + setParameterListExpression(assignmentExpression); + IASTExpression secondExpression = assignmentExpression(scope, kind, + key); + setParameterListExpression(null); + try { + assignmentExpression = astFactory.createExpression(scope, + IASTExpression.Kind.EXPRESSIONLIST, + assignmentExpression, secondExpression, null, null, + null, EMPTY_STRING, null); + } catch (ASTSemanticException e) { + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException("expression::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + } + return assignmentExpression; } /** * @param assignmentExpression */ - protected void setParameterListExpression(IASTExpression assignmentExpression) { + protected void setParameterListExpression( + IASTExpression assignmentExpression) { } /** * @param expression * @throws BacktrackException */ - protected IASTExpression assignmentExpression(IASTScope scope, CompletionKind kind, KeywordSetKey key) throws EndOfFileException, BacktrackException { - setCompletionValues(scope, kind, key ); + protected IASTExpression assignmentExpression(IASTScope scope, + CompletionKind kind, KeywordSetKey key) throws EndOfFileException, + BacktrackException { + setCompletionValues(scope, kind, key); if (LT(1) == IToken.t_throw) { - return throwExpression(scope,key); + return throwExpression(scope, key); } - IASTExpression conditionalExpression = conditionalExpression(scope,kind,key); + IASTExpression conditionalExpression = conditionalExpression(scope, + kind, key); // if the condition not taken, try assignment operators if (conditionalExpression != null - && conditionalExpression.getExpressionKind() - == IASTExpression.Kind.CONDITIONALEXPRESSION) + && conditionalExpression.getExpressionKind() == IASTExpression.Kind.CONDITIONALEXPRESSION) return conditionalExpression; switch (LT(1)) { case IToken.tASSIGN : - return assignmentOperatorExpression( - scope, - IASTExpression.Kind.ASSIGNMENTEXPRESSION_NORMAL, - conditionalExpression, kind,key); + return assignmentOperatorExpression(scope, + IASTExpression.Kind.ASSIGNMENTEXPRESSION_NORMAL, + conditionalExpression, kind, key); case IToken.tSTARASSIGN : - return assignmentOperatorExpression( - scope, - IASTExpression.Kind.ASSIGNMENTEXPRESSION_MULT, - conditionalExpression, kind,key); + return assignmentOperatorExpression(scope, + IASTExpression.Kind.ASSIGNMENTEXPRESSION_MULT, + conditionalExpression, kind, key); case IToken.tDIVASSIGN : - return assignmentOperatorExpression( - scope, - IASTExpression.Kind.ASSIGNMENTEXPRESSION_DIV, - conditionalExpression, kind,key); + return assignmentOperatorExpression(scope, + IASTExpression.Kind.ASSIGNMENTEXPRESSION_DIV, + conditionalExpression, kind, key); case IToken.tMODASSIGN : - return assignmentOperatorExpression( - scope, - IASTExpression.Kind.ASSIGNMENTEXPRESSION_MOD, - conditionalExpression, kind,key); + return assignmentOperatorExpression(scope, + IASTExpression.Kind.ASSIGNMENTEXPRESSION_MOD, + conditionalExpression, kind, key); case IToken.tPLUSASSIGN : - return assignmentOperatorExpression( - scope, - IASTExpression.Kind.ASSIGNMENTEXPRESSION_PLUS, - conditionalExpression, kind,key); + return assignmentOperatorExpression(scope, + IASTExpression.Kind.ASSIGNMENTEXPRESSION_PLUS, + conditionalExpression, kind, key); case IToken.tMINUSASSIGN : - return assignmentOperatorExpression( - scope, - IASTExpression.Kind.ASSIGNMENTEXPRESSION_MINUS, - conditionalExpression, kind,key); + return assignmentOperatorExpression(scope, + IASTExpression.Kind.ASSIGNMENTEXPRESSION_MINUS, + conditionalExpression, kind, key); case IToken.tSHIFTRASSIGN : - return assignmentOperatorExpression( - scope, - IASTExpression.Kind.ASSIGNMENTEXPRESSION_RSHIFT, - conditionalExpression, kind,key); + return assignmentOperatorExpression(scope, + IASTExpression.Kind.ASSIGNMENTEXPRESSION_RSHIFT, + conditionalExpression, kind, key); case IToken.tSHIFTLASSIGN : - return assignmentOperatorExpression( - scope, - IASTExpression.Kind.ASSIGNMENTEXPRESSION_LSHIFT, - conditionalExpression, kind,key); + return assignmentOperatorExpression(scope, + IASTExpression.Kind.ASSIGNMENTEXPRESSION_LSHIFT, + conditionalExpression, kind, key); case IToken.tAMPERASSIGN : - return assignmentOperatorExpression( - scope, - IASTExpression.Kind.ASSIGNMENTEXPRESSION_AND, - conditionalExpression, kind,key); + return assignmentOperatorExpression(scope, + IASTExpression.Kind.ASSIGNMENTEXPRESSION_AND, + conditionalExpression, kind, key); case IToken.tXORASSIGN : - return assignmentOperatorExpression( - scope, - IASTExpression.Kind.ASSIGNMENTEXPRESSION_XOR, - conditionalExpression, kind,key); + return assignmentOperatorExpression(scope, + IASTExpression.Kind.ASSIGNMENTEXPRESSION_XOR, + conditionalExpression, kind, key); case IToken.tBITORASSIGN : - return assignmentOperatorExpression( - scope, - IASTExpression.Kind.ASSIGNMENTEXPRESSION_OR, - conditionalExpression, kind,key); + return assignmentOperatorExpression(scope, + IASTExpression.Kind.ASSIGNMENTEXPRESSION_OR, + conditionalExpression, kind, key); } return conditionalExpression; } @@ -884,36 +893,29 @@ public class ExpressionParser implements IExpressionParser, IParserData { * @param expression * @throws BacktrackException */ - protected IASTExpression throwExpression(IASTScope scope, KeywordSetKey key) throws EndOfFileException, BacktrackException { - consume(IToken.t_throw); - setCompletionValues( scope, CompletionKind.SINGLE_NAME_REFERENCE, KeywordSetKey.EXPRESSION ); - IASTExpression throwExpression = null; - try - { - throwExpression = expression(scope, CompletionKind.SINGLE_NAME_REFERENCE, key); - } - catch (BacktrackException b) - { - } - try - { - return astFactory.createExpression( - scope, - IASTExpression.Kind.THROWEXPRESSION, - throwExpression, - null, - null, - null, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e) - { - throw backtrack; - } catch (Exception e) - { - logException( "throwExpression::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } + protected IASTExpression throwExpression(IASTScope scope, KeywordSetKey key) + throws EndOfFileException, BacktrackException { + IToken throwToken = consume(IToken.t_throw); + setCompletionValues(scope, CompletionKind.SINGLE_NAME_REFERENCE, + KeywordSetKey.EXPRESSION); + IASTExpression throwExpression = null; + try { + throwExpression = expression(scope, + CompletionKind.SINGLE_NAME_REFERENCE, key); + } catch (BacktrackException b) { + } + try { + return astFactory.createExpression(scope, + IASTExpression.Kind.THROWEXPRESSION, throwExpression, null, + null, null, null, EMPTY_STRING, null); + } catch (ASTSemanticException e) { + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException("throwExpression::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(throwToken.getOffset()); + + } + return null; } /** @@ -921,210 +923,173 @@ public class ExpressionParser implements IExpressionParser, IParserData { * @return * @throws BacktrackException */ - protected IASTExpression conditionalExpression(IASTScope scope, CompletionKind kind, KeywordSetKey key) throws BacktrackException, EndOfFileException { - IASTExpression firstExpression = logicalOrExpression(scope,kind,key); - if (LT(1) == IToken.tQUESTION) - { - consume(); - IASTExpression secondExpression = expression(scope,kind, key); - consume(IToken.tCOLON); - IASTExpression thirdExpression = assignmentExpression(scope,kind,key); - try - { - return astFactory.createExpression( - scope, - IASTExpression.Kind.CONDITIONALEXPRESSION, - firstExpression, - secondExpression, - thirdExpression, - null, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e) - { - throw backtrack; - } catch (Exception e) - { - logException( "conditionalExpression::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - } - return firstExpression; + protected IASTExpression conditionalExpression(IASTScope scope, + CompletionKind kind, KeywordSetKey key) throws BacktrackException, + EndOfFileException { + int startingOffset = LA(1).getOffset(); + IASTExpression firstExpression = logicalOrExpression(scope, kind, key); + if (LT(1) == IToken.tQUESTION) { + consume(); + IASTExpression secondExpression = expression(scope, kind, key); + consume(IToken.tCOLON); + IASTExpression thirdExpression = assignmentExpression(scope, kind, + key); + try { + return astFactory.createExpression(scope, + IASTExpression.Kind.CONDITIONALEXPRESSION, + firstExpression, secondExpression, thirdExpression, + null, null, EMPTY_STRING, null); + } catch (ASTSemanticException e) { + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException("conditionalExpression::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + } + return firstExpression; } /** * @param expression * @throws BacktrackException */ - protected IASTExpression logicalOrExpression(IASTScope scope, CompletionKind kind, KeywordSetKey key) throws BacktrackException, EndOfFileException { - IASTExpression firstExpression = logicalAndExpression(scope,kind,key); - while (LT(1) == IToken.tOR) - { - consume(); - IASTExpression secondExpression = logicalAndExpression(scope,kind,key); - - try - { - firstExpression = - astFactory.createExpression( - scope, - IASTExpression.Kind.LOGICALOREXPRESSION, - firstExpression, - secondExpression, - null, - null, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e) - { - throw backtrack; - } catch (Exception e) - { - logException( "logicalOrExpression::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - } - return firstExpression; + protected IASTExpression logicalOrExpression(IASTScope scope, + CompletionKind kind, KeywordSetKey key) throws BacktrackException, + EndOfFileException { + int startingOffset = LA(1).getOffset(); + IASTExpression firstExpression = logicalAndExpression(scope, kind, key); + while (LT(1) == IToken.tOR) { + consume(); + IASTExpression secondExpression = logicalAndExpression(scope, kind, + key); + + try { + firstExpression = astFactory.createExpression(scope, + IASTExpression.Kind.LOGICALOREXPRESSION, + firstExpression, secondExpression, null, null, null, + EMPTY_STRING, null); + } catch (ASTSemanticException e) { + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException("logicalOrExpression::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + } + return firstExpression; } /** * @param expression * @throws BacktrackException */ - protected IASTExpression logicalAndExpression(IASTScope scope, CompletionKind kind, KeywordSetKey key) throws BacktrackException, EndOfFileException { - IASTExpression firstExpression = inclusiveOrExpression( scope,kind,key ); - while (LT(1) == IToken.tAND) - { - consume(); - IASTExpression secondExpression = inclusiveOrExpression( scope,kind,key ); - try - { - firstExpression = - astFactory.createExpression( - scope, - IASTExpression.Kind.LOGICALANDEXPRESSION, - firstExpression, - secondExpression, - null, - null, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e) - { - throw backtrack; - } catch (Exception e) - { - logException( "logicalAndExpression::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - } - return firstExpression; + protected IASTExpression logicalAndExpression(IASTScope scope, + CompletionKind kind, KeywordSetKey key) throws BacktrackException, + EndOfFileException { + int startingOffset = LA(1).getOffset(); + IASTExpression firstExpression = inclusiveOrExpression(scope, kind, key); + while (LT(1) == IToken.tAND) { + consume(); + IASTExpression secondExpression = inclusiveOrExpression(scope, + kind, key); + try { + firstExpression = astFactory.createExpression(scope, + IASTExpression.Kind.LOGICALANDEXPRESSION, + firstExpression, secondExpression, null, null, null, + EMPTY_STRING, null); + } catch (ASTSemanticException e) { + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException("logicalAndExpression::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + } + return firstExpression; } /** * @param expression * @throws BacktrackException */ - protected IASTExpression inclusiveOrExpression(IASTScope scope, CompletionKind kind, KeywordSetKey key) throws BacktrackException, EndOfFileException { - IASTExpression firstExpression = exclusiveOrExpression(scope,kind,key); - while (LT(1) == IToken.tBITOR) - { - consume(); - IASTExpression secondExpression = exclusiveOrExpression(scope,kind,key); - - try - { - firstExpression = - astFactory.createExpression( - scope, - IASTExpression.Kind.INCLUSIVEOREXPRESSION, - firstExpression, - secondExpression, - null, - null, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e) - { - throw backtrack; - } catch (Exception e) - { - logException( "inclusiveOrExpression::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - } - return firstExpression; + protected IASTExpression inclusiveOrExpression(IASTScope scope, + CompletionKind kind, KeywordSetKey key) throws BacktrackException, + EndOfFileException { + int startingOffset = LA(1).getOffset(); + IASTExpression firstExpression = exclusiveOrExpression(scope, kind, key); + while (LT(1) == IToken.tBITOR) { + consume(); + IASTExpression secondExpression = exclusiveOrExpression(scope, + kind, key); + + try { + firstExpression = astFactory.createExpression(scope, + IASTExpression.Kind.INCLUSIVEOREXPRESSION, + firstExpression, secondExpression, null, null, null, + EMPTY_STRING, null); + } catch (ASTSemanticException e) { + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException("inclusiveOrExpression::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + } + return firstExpression; } /** * @param expression * @throws BacktrackException */ - protected IASTExpression exclusiveOrExpression(IASTScope scope, CompletionKind kind, KeywordSetKey key) throws BacktrackException, EndOfFileException { - IASTExpression firstExpression = andExpression( scope,kind, key ); - while (LT(1) == IToken.tXOR) - { - consume(); - - IASTExpression secondExpression = andExpression( scope,kind, key ); - - try - { - firstExpression = - astFactory.createExpression( - scope, - IASTExpression.Kind.EXCLUSIVEOREXPRESSION, - firstExpression, - secondExpression, - null, - null, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e) - { - throw backtrack; - } catch (Exception e) - { - logException( "exclusiveORExpression::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - } - return firstExpression; + protected IASTExpression exclusiveOrExpression(IASTScope scope, + CompletionKind kind, KeywordSetKey key) throws BacktrackException, + EndOfFileException { + int startingOffset = LA(1).getOffset(); + IASTExpression firstExpression = andExpression(scope, kind, key); + while (LT(1) == IToken.tXOR) { + consume(); + + IASTExpression secondExpression = andExpression(scope, kind, key); + + try { + firstExpression = astFactory.createExpression(scope, + IASTExpression.Kind.EXCLUSIVEOREXPRESSION, + firstExpression, secondExpression, null, null, null, + EMPTY_STRING, null); + } catch (ASTSemanticException e) { + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException("exclusiveORExpression::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + } + return firstExpression; } /** * @param expression * @throws BacktrackException */ - protected IASTExpression andExpression(IASTScope scope, CompletionKind kind, KeywordSetKey key) throws EndOfFileException, BacktrackException { - IASTExpression firstExpression = equalityExpression(scope,kind, key); - while (LT(1) == IToken.tAMPER) - { - consume(); - IASTExpression secondExpression = equalityExpression(scope,kind, key); - - try - { - firstExpression = - astFactory.createExpression( - scope, - IASTExpression.Kind.ANDEXPRESSION, - firstExpression, - secondExpression, - null, - null, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e) - { - throw backtrack; - } catch (Exception e) - { - logException("andExpression::createExpression()", e); //$NON-NLS-1$ - throw backtrack; - } - } - return firstExpression; + protected IASTExpression andExpression(IASTScope scope, + CompletionKind kind, KeywordSetKey key) throws EndOfFileException, + BacktrackException { + int startingOffset = LA(1).getOffset(); + IASTExpression firstExpression = equalityExpression(scope, kind, key); + while (LT(1) == IToken.tAMPER) { + consume(); + IASTExpression secondExpression = equalityExpression(scope, kind, + key); + + try { + firstExpression = astFactory.createExpression(scope, + IASTExpression.Kind.ANDEXPRESSION, firstExpression, + secondExpression, null, null, null, EMPTY_STRING, null); + } catch (ASTSemanticException e) { + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException("andExpression::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + } + return firstExpression; } /** @@ -1132,20 +1097,19 @@ public class ExpressionParser implements IExpressionParser, IParserData { * @param e */ public void logException(String methodName, Exception e) { - if( !(e instanceof EndOfFileException ) && e != null ) - { + if (!(e instanceof EndOfFileException) && e != null) { StringBuffer buffer = new StringBuffer(); - buffer.append( "Parser: Unexpected exception in "); //$NON-NLS-1$ - buffer.append( methodName ); - buffer.append( ":"); //$NON-NLS-1$ - buffer.append( e.getClass().getName() ); - buffer.append( "::"); //$NON-NLS-1$ - buffer.append( e.getMessage() ); - buffer.append( ". w/"); //$NON-NLS-1$ - buffer.append( scanner.toString() ); - if( log.isTracing() ) - log.traceLog( buffer.toString() ); - log.errorLog( buffer.toString() ); + buffer.append("Parser: Unexpected exception in "); //$NON-NLS-1$ + buffer.append(methodName); + buffer.append(":"); //$NON-NLS-1$ + buffer.append(e.getClass().getName()); + buffer.append("::"); //$NON-NLS-1$ + buffer.append(e.getMessage()); + buffer.append(". w/"); //$NON-NLS-1$ + buffer.append(scanner.toString()); + if (log.isTracing()) + log.traceLog(buffer.toString()); + log.errorLog(buffer.toString()); } } @@ -1153,315 +1117,267 @@ public class ExpressionParser implements IExpressionParser, IParserData { * @param expression * @throws BacktrackException */ - protected IASTExpression equalityExpression(IASTScope scope, CompletionKind kind, KeywordSetKey key) throws EndOfFileException, BacktrackException { - IASTExpression firstExpression = relationalExpression(scope,kind,key); - for (;;) - { - switch (LT(1)) - { - case IToken.tEQUAL : - case IToken.tNOTEQUAL : - IToken t = consume(); - IASTExpression secondExpression = - relationalExpression(scope,kind,key); - - try - { - firstExpression = - astFactory.createExpression( - scope, - (t.getType() == IToken.tEQUAL) - ? IASTExpression.Kind.EQUALITY_EQUALS - : IASTExpression.Kind.EQUALITY_NOTEQUALS, - firstExpression, - secondExpression, - null, - null, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e) - { - throw backtrack; - } catch (Exception e) - { - logException( "equalityExpression::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - break; - default : - return firstExpression; - } - } + protected IASTExpression equalityExpression(IASTScope scope, + CompletionKind kind, KeywordSetKey key) throws EndOfFileException, + BacktrackException { + int startingOffset = LA(1).getOffset(); + IASTExpression firstExpression = relationalExpression(scope, kind, key); + for (;;) { + switch (LT(1)) { + case IToken.tEQUAL : + case IToken.tNOTEQUAL : + IToken t = consume(); + IASTExpression secondExpression = relationalExpression( + scope, kind, key); + + try { + firstExpression = astFactory.createExpression(scope, (t + .getType() == IToken.tEQUAL) + ? IASTExpression.Kind.EQUALITY_EQUALS + : IASTExpression.Kind.EQUALITY_NOTEQUALS, + firstExpression, secondExpression, null, null, + null, EMPTY_STRING, null); + } catch (ASTSemanticException e) { + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException( + "equalityExpression::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + break; + default : + return firstExpression; + } + } } /** * @param expression * @throws BacktrackException */ - protected IASTExpression relationalExpression(IASTScope scope, CompletionKind kind, KeywordSetKey key) throws BacktrackException, EndOfFileException { - IASTExpression firstExpression = shiftExpression(scope,kind, key); - for (;;) - { - switch (LT(1)) - { - case IToken.tGT : - if( templateIdScopes != null && ((Integer)templateIdScopes.peek()).intValue() == IToken.tLT ){ - return firstExpression; - } - case IToken.tLT : - case IToken.tLTEQUAL : - case IToken.tGTEQUAL : - IToken mark = mark(); - int t = consume().getType(); - IASTExpression secondExpression = shiftExpression(scope,kind, key); - if (LA(1) == mark.getNext() ) - { - // we did not consume anything - // this is most likely an error - backup(mark); - return firstExpression; - } - IASTExpression.Kind expressionKind = null; - switch (t) - { - case IToken.tGT : - expressionKind = - IASTExpression.Kind.RELATIONAL_GREATERTHAN; - break; - case IToken.tLT : - expressionKind = IASTExpression.Kind.RELATIONAL_LESSTHAN; - break; - case IToken.tLTEQUAL : - expressionKind = - IASTExpression - .Kind - .RELATIONAL_LESSTHANEQUALTO; - break; - case IToken.tGTEQUAL : - expressionKind = - IASTExpression - .Kind - .RELATIONAL_GREATERTHANEQUALTO; - break; - } - try - { - firstExpression = - astFactory.createExpression( - scope, - expressionKind, - firstExpression, - secondExpression, - null, - null, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e) - { - throw backtrack; - } catch (Exception e) - { - logException( "relationalExpression::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - break; - default : - if( extension.isValidRelationalExpressionStart(language, LT(1))) - { - IASTExpression extensionExpression = extension.parseRelationalExpression(scope, this, kind, key, firstExpression ); - if( extensionExpression != null ) return extensionExpression; - } - return firstExpression; - } - } + protected IASTExpression relationalExpression(IASTScope scope, + CompletionKind kind, KeywordSetKey key) throws BacktrackException, + EndOfFileException { + int startingOffset = LA(1).getOffset(); + IASTExpression firstExpression = shiftExpression(scope, kind, key); + for (;;) { + switch (LT(1)) { + case IToken.tGT : + if (templateIdScopes != null + && ((Integer) templateIdScopes.peek()).intValue() == IToken.tLT) { + return firstExpression; + } + case IToken.tLT : + case IToken.tLTEQUAL : + case IToken.tGTEQUAL : + IToken mark = mark(); + int t = consume().getType(); + IASTExpression secondExpression = shiftExpression(scope, + kind, key); + if (LA(1) == mark.getNext()) { + // we did not consume anything + // this is most likely an error + backup(mark); + return firstExpression; + } + IASTExpression.Kind expressionKind = null; + switch (t) { + case IToken.tGT : + expressionKind = IASTExpression.Kind.RELATIONAL_GREATERTHAN; + break; + case IToken.tLT : + expressionKind = IASTExpression.Kind.RELATIONAL_LESSTHAN; + break; + case IToken.tLTEQUAL : + expressionKind = IASTExpression.Kind.RELATIONAL_LESSTHANEQUALTO; + break; + case IToken.tGTEQUAL : + expressionKind = IASTExpression.Kind.RELATIONAL_GREATERTHANEQUALTO; + break; + } + try { + firstExpression = astFactory.createExpression(scope, + expressionKind, firstExpression, + secondExpression, null, null, null, + EMPTY_STRING, null); + } catch (ASTSemanticException e) { + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException( + "relationalExpression::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + break; + default : + if (extension.isValidRelationalExpressionStart(language, + LT(1))) { + IASTExpression extensionExpression = extension + .parseRelationalExpression(scope, this, kind, + key, firstExpression); + if (extensionExpression != null) + return extensionExpression; + } + return firstExpression; + } + } } /** * @param expression * @throws BacktrackException */ - public IASTExpression shiftExpression(IASTScope scope, CompletionKind kind, KeywordSetKey key) throws BacktrackException, EndOfFileException { - IASTExpression firstExpression = additiveExpression(scope,kind,key); - for (;;) - { - switch (LT(1)) - { - case IToken.tSHIFTL : - case IToken.tSHIFTR : - IToken t = consume(); - IASTExpression secondExpression = - additiveExpression(scope,kind,key); - try - { - firstExpression = - astFactory.createExpression( - scope, - ((t.getType() == IToken.tSHIFTL) - ? IASTExpression.Kind.SHIFT_LEFT - : IASTExpression.Kind.SHIFT_RIGHT), - firstExpression, - secondExpression, - null, - null, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e) - { - throw backtrack; - } catch (Exception e) - { - logException( "shiftExpression::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - break; - default : - return firstExpression; - } - } + public IASTExpression shiftExpression(IASTScope scope, CompletionKind kind, + KeywordSetKey key) throws BacktrackException, EndOfFileException { + int startingOffset = LA(1).getOffset(); + IASTExpression firstExpression = additiveExpression(scope, kind, key); + for (;;) { + switch (LT(1)) { + case IToken.tSHIFTL : + case IToken.tSHIFTR : + IToken t = consume(); + IASTExpression secondExpression = additiveExpression(scope, + kind, key); + try { + firstExpression = astFactory.createExpression(scope, + ((t.getType() == IToken.tSHIFTL) + ? IASTExpression.Kind.SHIFT_LEFT + : IASTExpression.Kind.SHIFT_RIGHT), + firstExpression, secondExpression, null, null, + null, EMPTY_STRING, null); + } catch (ASTSemanticException e) { + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException("shiftExpression::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + break; + default : + return firstExpression; + } + } } /** * @param expression * @throws BacktrackException */ - protected IASTExpression additiveExpression(IASTScope scope, CompletionKind kind, KeywordSetKey key) throws BacktrackException, EndOfFileException { - IASTExpression firstExpression = multiplicativeExpression( scope, kind, key ); - for (;;) - { - switch (LT(1)) - { - case IToken.tPLUS : - case IToken.tMINUS : - IToken t = consume(); - IASTExpression secondExpression = - multiplicativeExpression(scope,kind,key); - try - { - firstExpression = - astFactory.createExpression( - scope, - ((t.getType() == IToken.tPLUS) - ? IASTExpression.Kind.ADDITIVE_PLUS - : IASTExpression.Kind.ADDITIVE_MINUS), - firstExpression, - secondExpression, - null, - null, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e) - { - throw backtrack; - } catch (Exception e) - { - logException( "additiveExpression::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - break; - default : - return firstExpression; - } - } + protected IASTExpression additiveExpression(IASTScope scope, + CompletionKind kind, KeywordSetKey key) throws BacktrackException, + EndOfFileException { + int startingOffset = LA(1).getOffset(); + IASTExpression firstExpression = multiplicativeExpression(scope, kind, + key); + for (;;) { + switch (LT(1)) { + case IToken.tPLUS : + case IToken.tMINUS : + IToken t = consume(); + IASTExpression secondExpression = multiplicativeExpression( + scope, kind, key); + try { + firstExpression = astFactory.createExpression(scope, + ((t.getType() == IToken.tPLUS) + ? IASTExpression.Kind.ADDITIVE_PLUS + : IASTExpression.Kind.ADDITIVE_MINUS), + firstExpression, secondExpression, null, null, + null, EMPTY_STRING, null); + } catch (ASTSemanticException e) { + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException( + "additiveExpression::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + break; + default : + return firstExpression; + } + } } /** * @param expression * @throws BacktrackException */ - protected IASTExpression multiplicativeExpression(IASTScope scope, CompletionKind kind, KeywordSetKey key) throws BacktrackException, EndOfFileException { - IASTExpression firstExpression = pmExpression(scope,kind,key); - for (;;) - { - switch (LT(1)) - { - case IToken.tSTAR : - case IToken.tDIV : - case IToken.tMOD : - IToken t = consume(); - IASTExpression secondExpression = pmExpression(scope,kind,key); - IASTExpression.Kind expressionKind = null; - switch (t.getType()) - { - case IToken.tSTAR : - expressionKind = IASTExpression.Kind.MULTIPLICATIVE_MULTIPLY; - break; - case IToken.tDIV : - expressionKind = IASTExpression.Kind.MULTIPLICATIVE_DIVIDE; - break; - case IToken.tMOD : - expressionKind = IASTExpression.Kind.MULTIPLICATIVE_MODULUS; - break; - } - try - { - firstExpression = - astFactory.createExpression( - scope, - expressionKind, - firstExpression, - secondExpression, - null, - null, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e) - { - firstExpression.freeReferences(astFactory.getReferenceManager()); - throw backtrack; - } catch (Exception e) - { - logException( "multiplicativeExpression::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - break; - default : - return firstExpression; - } - } + protected IASTExpression multiplicativeExpression(IASTScope scope, + CompletionKind kind, KeywordSetKey key) throws BacktrackException, + EndOfFileException { + int startingOffset = LA(1).getOffset(); + IASTExpression firstExpression = pmExpression(scope, kind, key); + for (;;) { + switch (LT(1)) { + case IToken.tSTAR : + case IToken.tDIV : + case IToken.tMOD : + IToken t = consume(); + IASTExpression secondExpression = pmExpression(scope, kind, + key); + IASTExpression.Kind expressionKind = null; + switch (t.getType()) { + case IToken.tSTAR : + expressionKind = IASTExpression.Kind.MULTIPLICATIVE_MULTIPLY; + break; + case IToken.tDIV : + expressionKind = IASTExpression.Kind.MULTIPLICATIVE_DIVIDE; + break; + case IToken.tMOD : + expressionKind = IASTExpression.Kind.MULTIPLICATIVE_MODULUS; + break; + } + try { + firstExpression = astFactory.createExpression(scope, + expressionKind, firstExpression, + secondExpression, null, null, null, + EMPTY_STRING, null); + } catch (ASTSemanticException e) { + firstExpression.freeReferences(astFactory + .getReferenceManager()); + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException( + "multiplicativeExpression::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + break; + default : + return firstExpression; + } + } } /** * @param expression * @throws BacktrackException */ - protected IASTExpression pmExpression(IASTScope scope, CompletionKind kind, KeywordSetKey key) throws EndOfFileException, BacktrackException { - IASTExpression firstExpression = castExpression(scope,kind,key); - for (;;) - { - switch (LT(1)) - { - case IToken.tDOTSTAR : - case IToken.tARROWSTAR : - IToken t = consume(); - IASTExpression secondExpression = - castExpression(scope,kind,key); - try - { - firstExpression = - astFactory.createExpression( - scope, - ((t.getType() == IToken.tDOTSTAR) - ? IASTExpression.Kind.PM_DOTSTAR - : IASTExpression.Kind.PM_ARROWSTAR), - firstExpression, - secondExpression, - null, - null, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e) - { - throw backtrack; - } catch (Exception e) - { - logException( "pmExpression::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - break; - default : - return firstExpression; - } - } + protected IASTExpression pmExpression(IASTScope scope, CompletionKind kind, + KeywordSetKey key) throws EndOfFileException, BacktrackException { + int startingOffset = LA(1).getOffset(); + IASTExpression firstExpression = castExpression(scope, kind, key); + for (;;) { + switch (LT(1)) { + case IToken.tDOTSTAR : + case IToken.tARROWSTAR : + IToken t = consume(); + IASTExpression secondExpression = castExpression(scope, + kind, key); + try { + firstExpression = astFactory.createExpression(scope, + ((t.getType() == IToken.tDOTSTAR) + ? IASTExpression.Kind.PM_DOTSTAR + : IASTExpression.Kind.PM_ARROWSTAR), + firstExpression, secondExpression, null, null, + null, EMPTY_STRING, null); + } catch (ASTSemanticException e) { + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException("pmExpression::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + break; + default : + return firstExpression; + } + } } /** @@ -1469,60 +1385,54 @@ public class ExpressionParser implements IExpressionParser, IParserData { * : unaryExpression * | "(" typeId ")" castExpression */ - protected IASTExpression castExpression(IASTScope scope, CompletionKind kind, KeywordSetKey key) throws EndOfFileException, BacktrackException { - // TO DO: we need proper symbol checkint to ensure type name - if (LT(1) == IToken.tLPAREN) - { - IToken mark = mark(); - consume(); - if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLPAREN ) ); } - boolean popped = false; - IASTTypeId typeId = null; - // If this isn't a type name, then we shouldn't be here - try - { - try - { - typeId = typeId(scope, false, getCastExpressionKind(kind)); - consume(IToken.tRPAREN); + protected IASTExpression castExpression(IASTScope scope, + CompletionKind kind, KeywordSetKey key) throws EndOfFileException, + BacktrackException { + // TO DO: we need proper symbol checkint to ensure type name + if (LT(1) == IToken.tLPAREN) { + int startingOffset = LA(1).getOffset(); + IToken mark = mark(); + consume(); + if (templateIdScopes != null) { + templateIdScopes.push(new Integer(IToken.tLPAREN)); + } + boolean popped = false; + IASTTypeId typeId = null; + // If this isn't a type name, then we shouldn't be here + try { + try { + typeId = typeId(scope, false, getCastExpressionKind(kind)); + consume(IToken.tRPAREN); + } catch (BacktrackException bte) { + backup(mark); + if (typeId != null) + typeId.freeReferences(astFactory.getReferenceManager()); + throw bte; } - catch( BacktrackException bte ) - { - backup( mark ); - if( typeId != null ) - typeId.freeReferences(astFactory.getReferenceManager()); - throw bte; + mark = null; // clean up mark so that we can garbage collect + if (templateIdScopes != null) { + templateIdScopes.pop(); + popped = true; } - mark = null; // clean up mark so that we can garbage collect - if( templateIdScopes != null ){ templateIdScopes.pop(); popped = true;} - IASTExpression castExpression = castExpression(scope,kind,key); - try - { - return astFactory.createExpression( - scope, - IASTExpression.Kind.CASTEXPRESSION, - castExpression, - null, - null, - typeId, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e) - { - throw backtrack; - } catch (Exception e) - { - logException( "castExpression::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - } - catch (BacktrackException b) - { - if( templateIdScopes != null && !popped ){ templateIdScopes.pop(); } - } - } - return unaryExpression(scope,kind, key); - + IASTExpression castExpression = castExpression(scope, kind, key); + try { + return astFactory.createExpression(scope, + IASTExpression.Kind.CASTEXPRESSION, castExpression, + null, null, typeId, null, EMPTY_STRING, null); + } catch (ASTSemanticException e) { + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException("castExpression::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + } catch (BacktrackException b) { + if (templateIdScopes != null && !popped) { + templateIdScopes.pop(); + } + } + } + return unaryExpression(scope, kind, key); + } /** @@ -1530,206 +1440,207 @@ public class ExpressionParser implements IExpressionParser, IParserData { * @return */ private CompletionKind getCastExpressionKind(CompletionKind kind) { - return ((kind == CompletionKind.SINGLE_NAME_REFERENCE || kind == CompletionKind.FUNCTION_REFERENCE)? kind : CompletionKind.TYPE_REFERENCE); + return ((kind == CompletionKind.SINGLE_NAME_REFERENCE || kind == CompletionKind.FUNCTION_REFERENCE) + ? kind + : CompletionKind.TYPE_REFERENCE); } - - /** * @param completionKind TODO * @throws BacktrackException */ - public IASTTypeId typeId(IASTScope scope, boolean skipArrayModifiers, CompletionKind completionKind) throws EndOfFileException, BacktrackException { + public IASTTypeId typeId(IASTScope scope, boolean skipArrayModifiers, + CompletionKind completionKind) throws EndOfFileException, + BacktrackException { IToken mark = mark(); ITokenDuple name = null; - boolean isConst = false, isVolatile = false; - boolean isSigned = false, isUnsigned = false; + boolean isConst = false, isVolatile = false; + boolean isSigned = false, isUnsigned = false; boolean isShort = false, isLong = false; - boolean isTypename = false; - + boolean isTypename = false; + IASTSimpleTypeSpecifier.Type kind = null; - do - { - try - { - name = name(scope, completionKind, KeywordSetKey.DECL_SPECIFIER_SEQUENCE ); - kind = IASTSimpleTypeSpecifier.Type.CLASS_OR_TYPENAME; - break; - } - catch (BacktrackException b) - { - // do nothing - } - - boolean encounteredType = false; - simpleMods : for (;;) - { - switch (LT(1)) - { - case IToken.t_signed : - consume(); - isSigned = true; - break; - - case IToken.t_unsigned : - consume(); - isUnsigned = true; - break; - - case IToken.t_short : - consume(); - isShort = true; - break; - - case IToken.t_long : - consume(); - isLong = true; - break; - - case IToken.t_const : - consume(); - isConst = true; - break; - - case IToken.t_volatile : - consume(); - isVolatile = true; - break; - - case IToken.tIDENTIFIER : - if( encounteredType ) break simpleMods; - encounteredType = true; - name = name(scope, completionKind, KeywordSetKey.EMPTY ); - kind = IASTSimpleTypeSpecifier.Type.CLASS_OR_TYPENAME; - break; - - case IToken.t_int : - if( encounteredType ) break simpleMods; - encounteredType = true; - kind = IASTSimpleTypeSpecifier.Type.INT; + do { + try { + name = name(scope, completionKind, + KeywordSetKey.DECL_SPECIFIER_SEQUENCE); + kind = IASTSimpleTypeSpecifier.Type.CLASS_OR_TYPENAME; + break; + } catch (BacktrackException b) { + // do nothing + } + + boolean encounteredType = false; + simpleMods : for (;;) { + switch (LT(1)) { + case IToken.t_signed : consume(); - break; - - case IToken.t_char : - if( encounteredType ) break simpleMods; - encounteredType = true; + isSigned = true; + break; + + case IToken.t_unsigned : + consume(); + isUnsigned = true; + break; + + case IToken.t_short : + consume(); + isShort = true; + break; + + case IToken.t_long : + consume(); + isLong = true; + break; + + case IToken.t_const : + consume(); + isConst = true; + break; + + case IToken.t_volatile : + consume(); + isVolatile = true; + break; + + case IToken.tIDENTIFIER : + if (encounteredType) + break simpleMods; + encounteredType = true; + name = name(scope, completionKind, KeywordSetKey.EMPTY); + kind = IASTSimpleTypeSpecifier.Type.CLASS_OR_TYPENAME; + break; + + case IToken.t_int : + if (encounteredType) + break simpleMods; + encounteredType = true; + kind = IASTSimpleTypeSpecifier.Type.INT; + consume(); + break; + + case IToken.t_char : + if (encounteredType) + break simpleMods; + encounteredType = true; kind = IASTSimpleTypeSpecifier.Type.CHAR; consume(); break; - - case IToken.t_bool : - if( encounteredType ) break simpleMods; - encounteredType = true; + + case IToken.t_bool : + if (encounteredType) + break simpleMods; + encounteredType = true; kind = IASTSimpleTypeSpecifier.Type.BOOL; consume(); break; - - case IToken.t_double : - if( encounteredType ) break simpleMods; - encounteredType = true; + + case IToken.t_double : + if (encounteredType) + break simpleMods; + encounteredType = true; kind = IASTSimpleTypeSpecifier.Type.DOUBLE; consume(); break; - - case IToken.t_float : - if( encounteredType ) break simpleMods; - encounteredType = true; + + case IToken.t_float : + if (encounteredType) + break simpleMods; + encounteredType = true; kind = IASTSimpleTypeSpecifier.Type.FLOAT; consume(); break; - - case IToken.t_wchar_t : - if( encounteredType ) break simpleMods; - encounteredType = true; + + case IToken.t_wchar_t : + if (encounteredType) + break simpleMods; + encounteredType = true; kind = IASTSimpleTypeSpecifier.Type.WCHAR_T; consume(); break; - - - case IToken.t_void : - if( encounteredType ) break simpleMods; - encounteredType = true; + + case IToken.t_void : + if (encounteredType) + break simpleMods; + encounteredType = true; kind = IASTSimpleTypeSpecifier.Type.VOID; consume(); break; - + case IToken.t__Bool : - if( encounteredType ) break simpleMods; - encounteredType = true; + if (encounteredType) + break simpleMods; + encounteredType = true; kind = IASTSimpleTypeSpecifier.Type._BOOL; consume(); break; - - default : - break simpleMods; - } - } - - if( kind != null ) break; - - if( isShort || isLong || isUnsigned || isSigned ) - { + + default : + break simpleMods; + } + } + + if (kind != null) + break; + + if (isShort || isLong || isUnsigned || isSigned) { kind = IASTSimpleTypeSpecifier.Type.INT; break; } - - if ( - LT(1) == IToken.t_typename - || LT(1) == IToken.t_struct - || LT(1) == IToken.t_class - || LT(1) == IToken.t_enum - || LT(1) == IToken.t_union) - { - consume(); - try - { - name = name(scope, completionKind, KeywordSetKey.EMPTY ); - kind = IASTSimpleTypeSpecifier.Type.CLASS_OR_TYPENAME; - } catch( BacktrackException b ) - { - backup( mark ); - throw backtrack; - } - } - - } while( false ); - - if( kind == null ) - throw backtrack; - - TypeId id = getTypeIdInstance(scope); + + if (LT(1) == IToken.t_typename || LT(1) == IToken.t_struct + || LT(1) == IToken.t_class || LT(1) == IToken.t_enum + || LT(1) == IToken.t_union) { + consume(); + try { + name = name(scope, completionKind, KeywordSetKey.EMPTY); + kind = IASTSimpleTypeSpecifier.Type.CLASS_OR_TYPENAME; + } catch (BacktrackException b) { + backup(mark); + throwBacktrack(mark.getOffset()); + } + } + + } while (false); + + if (kind == null) + throwBacktrack(mark.getOffset()); + + TypeId id = getTypeIdInstance(scope); IToken last = lastToken; - + //template parameters are consumed as part of name //lastToken = consumeTemplateParameters( last ); //if( lastToken == null ) lastToken = last; - - consumePointerOperators( id ); - if( lastToken == null ) lastToken = last; - - if( ! skipArrayModifiers ) - { - last = lastToken; - consumeArrayModifiers( id, scope ); - if( lastToken == null ) lastToken = last; + + consumePointerOperators(id); + if (lastToken == null) + lastToken = last; + + if (!skipArrayModifiers) { + last = lastToken; + consumeArrayModifiers(id, scope); + if (lastToken == null) + lastToken = last; } - - try - { + + try { String signature = "";//$NON-NLS-1$ - if( lastToken != null ) - signature = TokenFactory.createStringRepresentation(mark, lastToken); - return astFactory.createTypeId( scope, kind, isConst, isVolatile, isShort, isLong, isSigned, isUnsigned, isTypename, name, id.getPointerOperators(), id.getArrayModifiers(), signature); - } - catch (ASTSemanticException e) - { - backup( mark ); - throw backtrack; - } catch (Exception e) - { - logException( "typeId::createTypeId()", e ); //$NON-NLS-1$ - throw backtrack; - } + if (lastToken != null) + signature = TokenFactory.createStringRepresentation(mark, + lastToken); + return astFactory.createTypeId(scope, kind, isConst, isVolatile, + isShort, isLong, isSigned, isUnsigned, isTypename, name, id + .getPointerOperators(), id.getArrayModifiers(), + signature); + } catch (ASTSemanticException e) { + backup(mark); + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException("typeId::createTypeId()", e); //$NON-NLS-1$ + throwBacktrack(mark.getOffset()); + } + return null; } /** @@ -1744,45 +1655,37 @@ public class ExpressionParser implements IExpressionParser, IParserData { * @param expression * @throws BacktrackException */ - protected IASTExpression deleteExpression(IASTScope scope, CompletionKind kind, KeywordSetKey key) throws EndOfFileException, BacktrackException { - if (LT(1) == IToken.tCOLONCOLON) - { - // global scope - consume(IToken.tCOLONCOLON); - } - - consume(IToken.t_delete); - - boolean vectored = false; - if (LT(1) == IToken.tLBRACKET) - { - // array delete - consume(); - consume(IToken.tRBRACKET); - vectored = true; - } - IASTExpression castExpression = castExpression(scope,kind,key); - try - { - return astFactory.createExpression( - scope, - (vectored - ? IASTExpression.Kind.DELETE_VECTORCASTEXPRESSION - : IASTExpression.Kind.DELETE_CASTEXPRESSION), - castExpression, - null, - null, - null, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e) - { - throw backtrack; - } catch (Exception e) - { - logException( "deleteExpression::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } + protected IASTExpression deleteExpression(IASTScope scope, + CompletionKind kind, KeywordSetKey key) throws EndOfFileException, + BacktrackException { + int startingOffset = LA(1).getOffset(); + if (LT(1) == IToken.tCOLONCOLON) { + // global scope + consume(IToken.tCOLONCOLON); + } + + consume(IToken.t_delete); + + boolean vectored = false; + if (LT(1) == IToken.tLBRACKET) { + // array delete + consume(); + consume(IToken.tRBRACKET); + vectored = true; + } + IASTExpression castExpression = castExpression(scope, kind, key); + try { + return astFactory.createExpression(scope, (vectored + ? IASTExpression.Kind.DELETE_VECTORCASTEXPRESSION + : IASTExpression.Kind.DELETE_CASTEXPRESSION), + castExpression, null, null, null, null, EMPTY_STRING, null); + } catch (ASTSemanticException e) { + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException("deleteExpression::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + return null; } /** @@ -1801,723 +1704,655 @@ public class ExpressionParser implements IExpressionParser, IParserData { * directnewdeclarator [ constantexpression ] * newinitializer: ( expressionlist? ) */ - protected IASTExpression newExpression(IASTScope scope, KeywordSetKey key) throws BacktrackException, EndOfFileException { - setCompletionValues(scope, CompletionKind.NEW_TYPE_REFERENCE, KeywordSetKey.EMPTY); - if (LT(1) == IToken.tCOLONCOLON) - { - // global scope - consume(IToken.tCOLONCOLON); - } - consume(IToken.t_new); - boolean typeIdInParen = false; - boolean placementParseFailure = true; - IToken beforeSecondParen = null; - IToken backtrackMarker = null; - IASTTypeId typeId = null; + protected IASTExpression newExpression(IASTScope scope, KeywordSetKey key) + throws BacktrackException, EndOfFileException { + setCompletionValues(scope, CompletionKind.NEW_TYPE_REFERENCE, + KeywordSetKey.EMPTY); + int startingOffset = LA(1).getOffset(); + if (LT(1) == IToken.tCOLONCOLON) { + // global scope + consume(IToken.tCOLONCOLON); + } + consume(IToken.t_new); + boolean typeIdInParen = false; + boolean placementParseFailure = true; + IToken beforeSecondParen = null; + IToken backtrackMarker = null; + IASTTypeId typeId = null; ArrayList newPlacementExpressions = new ArrayList(); ArrayList newTypeIdExpressions = new ArrayList(); ArrayList newInitializerExpressions = new ArrayList(); - - if (LT(1) == IToken.tLPAREN) - { - consume(IToken.tLPAREN); - if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLPAREN ) ); } - try - { - // Try to consume placement list - // Note: since expressionList and expression are the same... - backtrackMarker = mark(); - newPlacementExpressions.add(expression(scope, CompletionKind.SINGLE_NAME_REFERENCE, key)); - consume(IToken.tRPAREN); - if( templateIdScopes != null ){ templateIdScopes.pop(); } //pop 1st Parent - placementParseFailure = false; - if (LT(1) == IToken.tLPAREN) - { - beforeSecondParen = mark(); - consume(IToken.tLPAREN); - if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLPAREN ) ); } //push 2nd Paren - typeIdInParen = true; - } - } - catch (BacktrackException e) - { - backup(backtrackMarker); - } - if (placementParseFailure) - { - // CASE: new (typeid-not-looking-as-placement) ... - // the first expression in () is not a placement - // - then it has to be typeId - typeId = typeId(scope, true, CompletionKind.NEW_TYPE_REFERENCE ); - consume(IToken.tRPAREN); - if( templateIdScopes != null ){ templateIdScopes.pop(); } //pop 1st Paren - } - else - { - if (!typeIdInParen) - { - if (LT(1) == IToken.tLBRACKET) - { - // CASE: new (typeid-looking-as-placement) [expr]... - // the first expression in () has been parsed as a placement; - // however, we assume that it was in fact typeId, and this - // new statement creates an array. - // Do nothing, fallback to array/initializer processing - } - else - { - // CASE: new (placement) typeid ... - // the first expression in () is parsed as a placement, - // and the next expression doesn't start with '(' or '[' - // - then it has to be typeId - try - { - backtrackMarker = mark(); - typeId = typeId(scope, true, CompletionKind.NEW_TYPE_REFERENCE); - } - catch (BacktrackException e) - { - // Hmmm, so it wasn't typeId after all... Then it is - // CASE: new (typeid-looking-as-placement) - backup(backtrackMarker); + + if (LT(1) == IToken.tLPAREN) { + consume(IToken.tLPAREN); + if (templateIdScopes != null) { + templateIdScopes.push(new Integer(IToken.tLPAREN)); + } + try { + // Try to consume placement list + // Note: since expressionList and expression are the same... + backtrackMarker = mark(); + newPlacementExpressions.add(expression(scope, + CompletionKind.SINGLE_NAME_REFERENCE, key)); + consume(IToken.tRPAREN); + if (templateIdScopes != null) { + templateIdScopes.pop(); + } //pop 1st Parent + placementParseFailure = false; + if (LT(1) == IToken.tLPAREN) { + beforeSecondParen = mark(); + consume(IToken.tLPAREN); + if (templateIdScopes != null) { + templateIdScopes.push(new Integer(IToken.tLPAREN)); + } //push 2nd Paren + typeIdInParen = true; + } + } catch (BacktrackException e) { + backup(backtrackMarker); + } + if (placementParseFailure) { + // CASE: new (typeid-not-looking-as-placement) ... + // the first expression in () is not a placement + // - then it has to be typeId + typeId = typeId(scope, true, CompletionKind.NEW_TYPE_REFERENCE); + consume(IToken.tRPAREN); + if (templateIdScopes != null) { + templateIdScopes.pop(); + } //pop 1st Paren + } else { + if (!typeIdInParen) { + if (LT(1) == IToken.tLBRACKET) { + // CASE: new (typeid-looking-as-placement) [expr]... + // the first expression in () has been parsed as a placement; + // however, we assume that it was in fact typeId, and this + // new statement creates an array. + // Do nothing, fallback to array/initializer processing + } else { + // CASE: new (placement) typeid ... + // the first expression in () is parsed as a placement, + // and the next expression doesn't start with '(' or '[' + // - then it has to be typeId + try { + backtrackMarker = mark(); + typeId = typeId(scope, true, + CompletionKind.NEW_TYPE_REFERENCE); + } catch (BacktrackException e) { + // Hmmm, so it wasn't typeId after all... Then it is + // CASE: new (typeid-looking-as-placement) + backup(backtrackMarker); // TODO fix this - return null; - } - } - } - else - { - // Tricky cases: first expression in () is parsed as a placement, - // and the next expression starts with '('. - // The problem is, the first expression might as well be a typeid - try - { - typeId = typeId(scope, true, CompletionKind.NEW_TYPE_REFERENCE); - consume(IToken.tRPAREN); - if( templateIdScopes != null ){ templateIdScopes.pop(); } //popping the 2nd Paren - - if (LT(1) == IToken.tLPAREN - || LT(1) == IToken.tLBRACKET) - { - // CASE: new (placement)(typeid)(initializer) - // CASE: new (placement)(typeid)[] ... - // Great, so far all our assumptions have been correct - // Do nothing, fallback to array/initializer processing - } - else - { - // CASE: new (placement)(typeid) - // CASE: new (typeid-looking-as-placement)(initializer-looking-as-typeid) - // Worst-case scenario - this cannot be resolved w/o more semantic information. - // Luckily, we don't need to know what was that - we only know that - // new-expression ends here. - try - { - setCompletionValues(scope, CompletionKind.NO_SUCH_KIND, KeywordSetKey.EMPTY); - return astFactory.createExpression( - scope, IASTExpression.Kind.NEW_TYPEID, - null, null, null, typeId, null, - EMPTY_STRING, astFactory.createNewDescriptor(newPlacementExpressions, newTypeIdExpressions, newInitializerExpressions)); + return null; + } + } + } else { + // Tricky cases: first expression in () is parsed as a placement, + // and the next expression starts with '('. + // The problem is, the first expression might as well be a typeid + try { + typeId = typeId(scope, true, + CompletionKind.NEW_TYPE_REFERENCE); + consume(IToken.tRPAREN); + if (templateIdScopes != null) { + templateIdScopes.pop(); + } //popping the 2nd Paren + + if (LT(1) == IToken.tLPAREN + || LT(1) == IToken.tLBRACKET) { + // CASE: new (placement)(typeid)(initializer) + // CASE: new (placement)(typeid)[] ... + // Great, so far all our assumptions have been correct + // Do nothing, fallback to array/initializer processing + } else { + // CASE: new (placement)(typeid) + // CASE: new (typeid-looking-as-placement)(initializer-looking-as-typeid) + // Worst-case scenario - this cannot be resolved w/o more semantic information. + // Luckily, we don't need to know what was that - we only know that + // new-expression ends here. + try { + setCompletionValues(scope, + CompletionKind.NO_SUCH_KIND, + KeywordSetKey.EMPTY); + return astFactory.createExpression(scope, + IASTExpression.Kind.NEW_TYPEID, null, + null, null, typeId, null, EMPTY_STRING, + astFactory.createNewDescriptor( + newPlacementExpressions, + newTypeIdExpressions, + newInitializerExpressions)); + } catch (ASTSemanticException e) { + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException( + "newExpression_1::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); } - catch (ASTSemanticException e) - { - throw backtrack; - } catch (Exception e) - { - logException( "newExpression_1::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - } - } - catch (BacktrackException e) - { - // CASE: new (typeid-looking-as-placement)(initializer-not-looking-as-typeid) - // Fallback to initializer processing - backup(beforeSecondParen); - if( templateIdScopes != null ){ templateIdScopes.pop(); }//pop that 2nd paren - } - } - } - } - else - { - // CASE: new typeid ... - // new parameters do not start with '(' - // i.e it has to be a plain typeId - typeId = typeId(scope, true, CompletionKind.NEW_TYPE_REFERENCE); - } - while (LT(1) == IToken.tLBRACKET) - { - // array new - consume(); - - if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLBRACKET ) ); } - - newTypeIdExpressions.add(assignmentExpression(scope, CompletionKind.SINGLE_NAME_REFERENCE,key)); - consume(IToken.tRBRACKET); - - if( templateIdScopes != null ){ templateIdScopes.pop(); } - } - // newinitializer - if (LT(1) == IToken.tLPAREN) - { - consume(IToken.tLPAREN); - setCurrentFunctionName( (( typeId != null ) ? typeId.getFullSignature() : EMPTY_STRING)); - setCompletionValues( scope, CompletionKind.CONSTRUCTOR_REFERENCE ); - if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLPAREN ) ); } - - //we want to know the difference between no newInitializer and an empty new Initializer - //if the next token is the RPAREN, then we have an Empty expression in our list. - newInitializerExpressions.add(expression(scope, CompletionKind.CONSTRUCTOR_REFERENCE, key)); - - setCurrentFunctionName( EMPTY_STRING ); - consume(IToken.tRPAREN); - if( templateIdScopes != null ){ templateIdScopes.pop(); } - } - setCompletionValues(scope, CompletionKind.NO_SUCH_KIND, KeywordSetKey.EMPTY); - try - { - return astFactory.createExpression( - scope, IASTExpression.Kind.NEW_TYPEID, - null, null, null, typeId, null, - EMPTY_STRING, astFactory.createNewDescriptor(newPlacementExpressions, newTypeIdExpressions, newInitializerExpressions)); + } + } catch (BacktrackException e) { + // CASE: new (typeid-looking-as-placement)(initializer-not-looking-as-typeid) + // Fallback to initializer processing + backup(beforeSecondParen); + if (templateIdScopes != null) { + templateIdScopes.pop(); + }//pop that 2nd paren + } + } + } + } else { + // CASE: new typeid ... + // new parameters do not start with '(' + // i.e it has to be a plain typeId + typeId = typeId(scope, true, CompletionKind.NEW_TYPE_REFERENCE); } - catch (ASTSemanticException e) - { + while (LT(1) == IToken.tLBRACKET) { + // array new + consume(); + + if (templateIdScopes != null) { + templateIdScopes.push(new Integer(IToken.tLBRACKET)); + } + + newTypeIdExpressions.add(assignmentExpression(scope, + CompletionKind.SINGLE_NAME_REFERENCE, key)); + consume(IToken.tRBRACKET); + + if (templateIdScopes != null) { + templateIdScopes.pop(); + } + } + // newinitializer + if (LT(1) == IToken.tLPAREN) { + consume(IToken.tLPAREN); + setCurrentFunctionName(((typeId != null) ? typeId + .getFullSignature() : EMPTY_STRING)); + setCompletionValues(scope, CompletionKind.CONSTRUCTOR_REFERENCE); + if (templateIdScopes != null) { + templateIdScopes.push(new Integer(IToken.tLPAREN)); + } + + //we want to know the difference between no newInitializer and an empty new Initializer + //if the next token is the RPAREN, then we have an Empty expression in our list. + newInitializerExpressions.add(expression(scope, + CompletionKind.CONSTRUCTOR_REFERENCE, key)); + + setCurrentFunctionName(EMPTY_STRING); + consume(IToken.tRPAREN); + if (templateIdScopes != null) { + templateIdScopes.pop(); + } + } + setCompletionValues(scope, CompletionKind.NO_SUCH_KIND, + KeywordSetKey.EMPTY); + try { + return astFactory.createExpression(scope, + IASTExpression.Kind.NEW_TYPEID, null, null, null, typeId, + null, EMPTY_STRING, astFactory.createNewDescriptor( + newPlacementExpressions, newTypeIdExpressions, + newInitializerExpressions)); + } catch (ASTSemanticException e) { + throwBacktrack(e.getProblem()); return null; - } catch (Exception e) - { - logException( "newExpression_2::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - + } catch (Exception e) { + logException("newExpression_2::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + return null; } /** * @param functionName */ - protected void setCurrentFunctionName(String functionName ) { + protected void setCurrentFunctionName(String functionName) { } /** * @param expression * @throws BacktrackException */ - public IASTExpression unaryExpression(IASTScope scope, CompletionKind kind, KeywordSetKey key) throws EndOfFileException, BacktrackException { - switch (LT(1)) - { - case IToken.tSTAR : - consume(); - return unaryOperatorCastExpression(scope, - IASTExpression.Kind.UNARY_STAR_CASTEXPRESSION,kind,key); - case IToken.tAMPER : + public IASTExpression unaryExpression(IASTScope scope, CompletionKind kind, + KeywordSetKey key) throws EndOfFileException, BacktrackException { + int startingOffset = LA(1).getOffset(); + switch (LT(1)) { + case IToken.tSTAR : consume(); - return unaryOperatorCastExpression(scope, - IASTExpression.Kind.UNARY_AMPSND_CASTEXPRESSION,kind,key); - case IToken.tPLUS : + return unaryOperatorCastExpression(scope, + IASTExpression.Kind.UNARY_STAR_CASTEXPRESSION, kind, + key); + case IToken.tAMPER : consume(); - return unaryOperatorCastExpression(scope, - IASTExpression.Kind.UNARY_PLUS_CASTEXPRESSION,kind,key); - case IToken.tMINUS : - consume(); - return unaryOperatorCastExpression(scope, - IASTExpression.Kind.UNARY_MINUS_CASTEXPRESSION,kind,key); - case IToken.tNOT : - consume(); - return unaryOperatorCastExpression(scope, - IASTExpression.Kind.UNARY_NOT_CASTEXPRESSION,kind,key); - case IToken.tCOMPL : - consume(); - return unaryOperatorCastExpression(scope, - IASTExpression.Kind.UNARY_TILDE_CASTEXPRESSION,kind,key); - case IToken.tINCR : - consume(); - return unaryOperatorCastExpression(scope, - IASTExpression.Kind.UNARY_INCREMENT,kind,key); - case IToken.tDECR : - consume(); - return unaryOperatorCastExpression(scope, - IASTExpression.Kind.UNARY_DECREMENT,kind,key); - case IToken.t_sizeof : - consume(IToken.t_sizeof); - IToken mark = LA(1); - IASTTypeId d = null; - IASTExpression unaryExpression = null; - if (LT(1) == IToken.tLPAREN) - { - try - { - consume(IToken.tLPAREN); - d = typeId(scope, false, CompletionKind.SINGLE_NAME_REFERENCE); - consume(IToken.tRPAREN); - } - catch (BacktrackException bt) - { - backup(mark); - unaryExpression = unaryExpression(scope,kind, key); - } - } - else - { - unaryExpression = unaryExpression(scope,kind, key); - } - if (unaryExpression == null) - try - { - return astFactory.createExpression( - scope, - IASTExpression.Kind.UNARY_SIZEOF_TYPEID, - null, - null, - null, - d, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e) - { - throw backtrack; - } catch (Exception e) - { - logException( "unaryExpression_1::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - try - { - return astFactory.createExpression( - scope, - IASTExpression.Kind.UNARY_SIZEOF_UNARYEXPRESSION, - unaryExpression, - null, - null, - null, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e1) - { - throw backtrack; - } catch (Exception e) - { - logException( "unaryExpression_1::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - case IToken.t_new : - return newExpression(scope,key); - case IToken.t_delete : - return deleteExpression(scope,kind,key); - case IToken.tCOLONCOLON : - if( queryLookaheadCapability(2)) - { - switch (LT(2)) - { - case IToken.t_new : - return newExpression(scope,key); - case IToken.t_delete : - return deleteExpression(scope,kind,key); - default : - return postfixExpression(scope,kind,key); - } - } - default : - if( extension.isValidUnaryExpressionStart( LT(1))) - { - IASTExpression extensionExpression = extension.parseUnaryExpression(scope,this,kind, key); - if( extensionExpression != null ) return extensionExpression; - } - return postfixExpression(scope,kind,key); - } - } - - /** - * @param expression - * @throws BacktrackException - */ - protected IASTExpression postfixExpression(IASTScope scope, CompletionKind kind, KeywordSetKey key) throws EndOfFileException, BacktrackException { - IASTExpression firstExpression = null; - boolean isTemplate = false; - - setCompletionValues( scope, kind, key ); - switch (LT(1)) - { - case IToken.t_typename : - consume(IToken.t_typename); - - boolean templateTokenConsumed = false; - if( LT(1) == IToken.t_template ) - { - consume( IToken.t_template ); - templateTokenConsumed = true; + return unaryOperatorCastExpression(scope, + IASTExpression.Kind.UNARY_AMPSND_CASTEXPRESSION, kind, + key); + case IToken.tPLUS : + consume(); + return unaryOperatorCastExpression(scope, + IASTExpression.Kind.UNARY_PLUS_CASTEXPRESSION, kind, + key); + case IToken.tMINUS : + consume(); + return unaryOperatorCastExpression(scope, + IASTExpression.Kind.UNARY_MINUS_CASTEXPRESSION, kind, + key); + case IToken.tNOT : + consume(); + return unaryOperatorCastExpression(scope, + IASTExpression.Kind.UNARY_NOT_CASTEXPRESSION, kind, key); + case IToken.tCOMPL : + consume(); + return unaryOperatorCastExpression(scope, + IASTExpression.Kind.UNARY_TILDE_CASTEXPRESSION, kind, + key); + case IToken.tINCR : + consume(); + return unaryOperatorCastExpression(scope, + IASTExpression.Kind.UNARY_INCREMENT, kind, key); + case IToken.tDECR : + consume(); + return unaryOperatorCastExpression(scope, + IASTExpression.Kind.UNARY_DECREMENT, kind, key); + case IToken.t_sizeof : + consume(IToken.t_sizeof); + IToken mark = LA(1); + IASTTypeId d = null; + IASTExpression unaryExpression = null; + if (LT(1) == IToken.tLPAREN) { + try { + consume(IToken.tLPAREN); + d = typeId(scope, false, + CompletionKind.SINGLE_NAME_REFERENCE); + consume(IToken.tRPAREN); + } catch (BacktrackException bt) { + backup(mark); + unaryExpression = unaryExpression(scope, kind, key); + } + } else { + unaryExpression = unaryExpression(scope, kind, key); } - ITokenDuple nestedName = name(scope, CompletionKind.TYPE_REFERENCE, KeywordSetKey.EMPTY); - - consume( IToken.tLPAREN ); - if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLPAREN ) ); } - IASTExpression expressionList = expression( scope, CompletionKind.TYPE_REFERENCE, key ); - consume( IToken.tRPAREN ); - if( templateIdScopes != null ){ templateIdScopes.pop(); } - try { - firstExpression = - astFactory.createExpression( scope, - ( templateTokenConsumed ? IASTExpression.Kind.POSTFIX_TYPENAME_TEMPLATEID : IASTExpression.Kind.POSTFIX_TYPENAME_IDENTIFIER ), - expressionList, - null, - null, - null, - nestedName, - EMPTY_STRING, - null ); - } catch (ASTSemanticException ase ) { - throw backtrack; - } catch (Exception e) - { - logException( "postfixExpression_1::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - break; - // simple-type-specifier ( assignment-expression , .. ) - case IToken.t_char : - firstExpression = - simpleTypeConstructorExpression(scope, - IASTExpression.Kind.POSTFIX_SIMPLETYPE_CHAR,key); - break; - case IToken.t_wchar_t : - firstExpression = - simpleTypeConstructorExpression(scope, - IASTExpression.Kind.POSTFIX_SIMPLETYPE_WCHART,key); - break; - case IToken.t_bool : - firstExpression = - simpleTypeConstructorExpression(scope, - IASTExpression.Kind.POSTFIX_SIMPLETYPE_BOOL,key); - break; - case IToken.t_short : - firstExpression = - simpleTypeConstructorExpression(scope, - IASTExpression.Kind.POSTFIX_SIMPLETYPE_SHORT,key); - break; - case IToken.t_int : - firstExpression = - simpleTypeConstructorExpression(scope, - IASTExpression.Kind.POSTFIX_SIMPLETYPE_INT,key); - break; - case IToken.t_long : - firstExpression = - simpleTypeConstructorExpression(scope, - IASTExpression.Kind.POSTFIX_SIMPLETYPE_LONG,key); - break; - case IToken.t_signed : - firstExpression = - simpleTypeConstructorExpression(scope, - IASTExpression.Kind.POSTFIX_SIMPLETYPE_SIGNED,key); - break; - case IToken.t_unsigned : - firstExpression = - simpleTypeConstructorExpression(scope, - IASTExpression.Kind.POSTFIX_SIMPLETYPE_UNSIGNED,key); - break; - case IToken.t_float : - firstExpression = - simpleTypeConstructorExpression(scope, - IASTExpression.Kind.POSTFIX_SIMPLETYPE_FLOAT,key); - break; - case IToken.t_double : - firstExpression = - simpleTypeConstructorExpression( scope, - IASTExpression.Kind.POSTFIX_SIMPLETYPE_DOUBLE,key); - break; - case IToken.t_dynamic_cast : - firstExpression = - specialCastExpression(scope, - IASTExpression.Kind.POSTFIX_DYNAMIC_CAST,key); - break; - case IToken.t_static_cast : - firstExpression = - specialCastExpression(scope, - IASTExpression.Kind.POSTFIX_STATIC_CAST,key); - break; - case IToken.t_reinterpret_cast : - firstExpression = - specialCastExpression(scope, - IASTExpression.Kind.POSTFIX_REINTERPRET_CAST,key); - break; - case IToken.t_const_cast : - firstExpression = - specialCastExpression(scope, - IASTExpression.Kind.POSTFIX_CONST_CAST,key); - break; - case IToken.t_typeid : - consume(); - consume(IToken.tLPAREN); - if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLPAREN ) ); } - boolean isTypeId = true; - IASTExpression lhs = null; - IASTTypeId typeId = null; - try - { - typeId = typeId(scope, false, CompletionKind.TYPE_REFERENCE); - } - catch (BacktrackException b) - { - isTypeId = false; - lhs = expression(scope, CompletionKind.TYPE_REFERENCE, key); - } - consume(IToken.tRPAREN); - if( templateIdScopes != null ){ templateIdScopes.pop(); } - try - { - firstExpression = - astFactory.createExpression( - scope, - (isTypeId - ? IASTExpression.Kind.POSTFIX_TYPEID_TYPEID - : IASTExpression.Kind.POSTFIX_TYPEID_EXPRESSION), - lhs, - null, - null, - typeId, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e6) - { - failParse(); - throw backtrack; - } catch (Exception e) - { - logException( "postfixExpression_2::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - break; - default : - firstExpression = primaryExpression(scope, kind, key); - } - IASTExpression secondExpression = null; - for (;;) - { - switch (LT(1)) - { - case IToken.tLBRACKET : - // array access - consume(IToken.tLBRACKET); - if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLBRACKET ) ); } - secondExpression = expression(scope, CompletionKind.SINGLE_NAME_REFERENCE, key); - consume(IToken.tRBRACKET); - if( templateIdScopes != null ){ templateIdScopes.pop(); } - try - { - firstExpression = - astFactory.createExpression( - scope, - IASTExpression.Kind.POSTFIX_SUBSCRIPT, - firstExpression, - secondExpression, - null, - null, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e2) - { - failParse(); - throw backtrack; - } catch (Exception e) - { - logException( "postfixExpression_3::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - break; - case IToken.tLPAREN : - // function call - consume(IToken.tLPAREN); - IASTNode context = null; - if( firstExpression != null ) - { - if( firstExpression.getExpressionKind() == IASTExpression.Kind.ID_EXPRESSION ) - setCurrentFunctionName( firstExpression.getIdExpression() ); - else if( firstExpression.getRHSExpression() != null && - firstExpression.getRHSExpression().getIdExpression() != null ) - { - setCurrentFunctionName( firstExpression.getRHSExpression().getIdExpression() ); - context = astFactory.expressionToMostPreciseASTNode( scope, firstExpression.getLHSExpression() ); - } - } - - if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLPAREN ) ); } - setCompletionValues(scope, CompletionKind.FUNCTION_REFERENCE, context ); - secondExpression = expression(scope, CompletionKind.FUNCTION_REFERENCE, key); - setCurrentFunctionName( EMPTY_STRING ); - consume(IToken.tRPAREN); - if( templateIdScopes != null ){ templateIdScopes.pop(); } - try - { - firstExpression = - astFactory.createExpression( - scope, - IASTExpression.Kind.POSTFIX_FUNCTIONCALL, - firstExpression, - secondExpression, - null, - null, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e3) - { - failParse(); - throw backtrack; - } catch (Exception e) - { - logException( "postfixExpression_4::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - break; - case IToken.tINCR : - consume(IToken.tINCR); - try - { - firstExpression = - astFactory.createExpression( - scope, - IASTExpression.Kind.POSTFIX_INCREMENT, - firstExpression, - null, - null, - null, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e1) - { - failParse(); - throw backtrack; - } catch (Exception e) - { - logException( "postfixExpression_5::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - break; - case IToken.tDECR : - consume(); - try - { - firstExpression = - astFactory.createExpression( - scope, - IASTExpression.Kind.POSTFIX_DECREMENT, - firstExpression, - null, - null, - null, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e4) - { - failParse(); - throw backtrack; - } catch (Exception e) - { - logException( "postfixExpression_6::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - break; - case IToken.tDOT : - // member access - consume(IToken.tDOT); - - if( queryLookaheadCapability() ) - if (LT(1) == IToken.t_template) - { - consume(IToken.t_template); - isTemplate = true; - } + if (unaryExpression == null) + try { + return astFactory.createExpression(scope, + IASTExpression.Kind.UNARY_SIZEOF_TYPEID, null, + null, null, d, null, EMPTY_STRING, null); + } catch (ASTSemanticException e) { + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException("unaryExpression_1::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + try { + return astFactory.createExpression(scope, + IASTExpression.Kind.UNARY_SIZEOF_UNARYEXPRESSION, + unaryExpression, null, null, null, null, + EMPTY_STRING, null); + } catch (ASTSemanticException e1) { + throwBacktrack(e1.getProblem()); + } catch (Exception e) { + logException("unaryExpression_1::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + case IToken.t_new : + return newExpression(scope, key); + case IToken.t_delete : + return deleteExpression(scope, kind, key); + case IToken.tCOLONCOLON : + if (queryLookaheadCapability(2)) { + switch (LT(2)) { + case IToken.t_new : + return newExpression(scope, key); + case IToken.t_delete : + return deleteExpression(scope, kind, key); + default : + return postfixExpression(scope, kind, key); + } + } + default : + if (extension.isValidUnaryExpressionStart(LT(1))) { + IASTExpression extensionExpression = extension + .parseUnaryExpression(scope, this, kind, key); + if (extensionExpression != null) + return extensionExpression; + } + return postfixExpression(scope, kind, key); + } + } - Kind memberCompletionKind = (isTemplate - ? IASTExpression.Kind.POSTFIX_DOT_TEMPL_IDEXPRESS - : IASTExpression.Kind.POSTFIX_DOT_IDEXPRESSION); - - setCompletionValues(scope, CompletionKind.MEMBER_REFERENCE, KeywordSetKey.EMPTY, firstExpression, memberCompletionKind ); - secondExpression = primaryExpression(scope, CompletionKind.MEMBER_REFERENCE, key); - if( secondExpression != null && secondExpression.getExpressionKind() == Kind.ID_EXPRESSION && secondExpression.getIdExpression().indexOf( '~') != -1 ) - memberCompletionKind = Kind.POSTFIX_DOT_DESTRUCTOR; - - try - { - firstExpression = - astFactory.createExpression( - scope, - memberCompletionKind, - firstExpression, - secondExpression, - null, - null, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e5) - { - failParse(); - throw backtrack; - } catch (Exception e) - { - logException( "postfixExpression_7::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - break; - case IToken.tARROW : - // member access - consume(IToken.tARROW); - - if( queryLookaheadCapability() ) - if (LT(1) == IToken.t_template) - { - consume(IToken.t_template); - isTemplate = true; - } + /** + * @param expression + * @throws BacktrackException + */ + protected IASTExpression postfixExpression(IASTScope scope, + CompletionKind kind, KeywordSetKey key) throws EndOfFileException, + BacktrackException { + int startingOffset = LA(1).getOffset(); + IASTExpression firstExpression = null; + boolean isTemplate = false; - Kind arrowCompletionKind = (isTemplate - ? IASTExpression.Kind.POSTFIX_ARROW_TEMPL_IDEXP - : IASTExpression.Kind.POSTFIX_ARROW_IDEXPRESSION); + setCompletionValues(scope, kind, key); + switch (LT(1)) { + case IToken.t_typename : + consume(IToken.t_typename); - setCompletionValues(scope, CompletionKind.MEMBER_REFERENCE, KeywordSetKey.EMPTY, firstExpression, arrowCompletionKind ); - secondExpression = primaryExpression(scope, CompletionKind.MEMBER_REFERENCE, key); + boolean templateTokenConsumed = false; + if (LT(1) == IToken.t_template) { + consume(IToken.t_template); + templateTokenConsumed = true; + } + ITokenDuple nestedName = name(scope, + CompletionKind.TYPE_REFERENCE, KeywordSetKey.EMPTY); - if( secondExpression != null && secondExpression.getExpressionKind() == Kind.ID_EXPRESSION && secondExpression.getIdExpression().indexOf( '~') != -1 ) - arrowCompletionKind = Kind.POSTFIX_ARROW_DESTRUCTOR; - try - { - firstExpression = - astFactory.createExpression( - scope, - arrowCompletionKind, - firstExpression, - secondExpression, - null, - null, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e) - { - failParse(); - throw backtrack; - } catch (Exception e) - { - logException( "postfixExpression_8::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - break; - default : - return firstExpression; - } - } + consume(IToken.tLPAREN); + if (templateIdScopes != null) { + templateIdScopes.push(new Integer(IToken.tLPAREN)); + } + IASTExpression expressionList = expression(scope, + CompletionKind.TYPE_REFERENCE, key); + consume(IToken.tRPAREN); + if (templateIdScopes != null) { + templateIdScopes.pop(); + } + try { + firstExpression = astFactory + .createExpression( + scope, + (templateTokenConsumed + ? IASTExpression.Kind.POSTFIX_TYPENAME_TEMPLATEID + : IASTExpression.Kind.POSTFIX_TYPENAME_IDENTIFIER), + expressionList, null, null, null, + nestedName, EMPTY_STRING, null); + } catch (ASTSemanticException ase) { + throwBacktrack(ase.getProblem()); + } catch (Exception e) { + logException("postfixExpression_1::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + break; + // simple-type-specifier ( assignment-expression , .. ) + case IToken.t_char : + firstExpression = simpleTypeConstructorExpression(scope, + IASTExpression.Kind.POSTFIX_SIMPLETYPE_CHAR, key); + break; + case IToken.t_wchar_t : + firstExpression = simpleTypeConstructorExpression(scope, + IASTExpression.Kind.POSTFIX_SIMPLETYPE_WCHART, key); + break; + case IToken.t_bool : + firstExpression = simpleTypeConstructorExpression(scope, + IASTExpression.Kind.POSTFIX_SIMPLETYPE_BOOL, key); + break; + case IToken.t_short : + firstExpression = simpleTypeConstructorExpression(scope, + IASTExpression.Kind.POSTFIX_SIMPLETYPE_SHORT, key); + break; + case IToken.t_int : + firstExpression = simpleTypeConstructorExpression(scope, + IASTExpression.Kind.POSTFIX_SIMPLETYPE_INT, key); + break; + case IToken.t_long : + firstExpression = simpleTypeConstructorExpression(scope, + IASTExpression.Kind.POSTFIX_SIMPLETYPE_LONG, key); + break; + case IToken.t_signed : + firstExpression = simpleTypeConstructorExpression(scope, + IASTExpression.Kind.POSTFIX_SIMPLETYPE_SIGNED, key); + break; + case IToken.t_unsigned : + firstExpression = simpleTypeConstructorExpression(scope, + IASTExpression.Kind.POSTFIX_SIMPLETYPE_UNSIGNED, key); + break; + case IToken.t_float : + firstExpression = simpleTypeConstructorExpression(scope, + IASTExpression.Kind.POSTFIX_SIMPLETYPE_FLOAT, key); + break; + case IToken.t_double : + firstExpression = simpleTypeConstructorExpression(scope, + IASTExpression.Kind.POSTFIX_SIMPLETYPE_DOUBLE, key); + break; + case IToken.t_dynamic_cast : + firstExpression = specialCastExpression(scope, + IASTExpression.Kind.POSTFIX_DYNAMIC_CAST, key); + break; + case IToken.t_static_cast : + firstExpression = specialCastExpression(scope, + IASTExpression.Kind.POSTFIX_STATIC_CAST, key); + break; + case IToken.t_reinterpret_cast : + firstExpression = specialCastExpression(scope, + IASTExpression.Kind.POSTFIX_REINTERPRET_CAST, key); + break; + case IToken.t_const_cast : + firstExpression = specialCastExpression(scope, + IASTExpression.Kind.POSTFIX_CONST_CAST, key); + break; + case IToken.t_typeid : + consume(); + consume(IToken.tLPAREN); + if (templateIdScopes != null) { + templateIdScopes.push(new Integer(IToken.tLPAREN)); + } + boolean isTypeId = true; + IASTExpression lhs = null; + IASTTypeId typeId = null; + try { + typeId = typeId(scope, false, CompletionKind.TYPE_REFERENCE); + } catch (BacktrackException b) { + isTypeId = false; + lhs = expression(scope, CompletionKind.TYPE_REFERENCE, key); + } + consume(IToken.tRPAREN); + if (templateIdScopes != null) { + templateIdScopes.pop(); + } + try { + firstExpression = astFactory + .createExpression( + scope, + (isTypeId + ? IASTExpression.Kind.POSTFIX_TYPEID_TYPEID + : IASTExpression.Kind.POSTFIX_TYPEID_EXPRESSION), + lhs, null, null, typeId, null, + EMPTY_STRING, null); + } catch (ASTSemanticException e6) { + throwBacktrack(e6.getProblem()); + } catch (Exception e) { + logException("postfixExpression_2::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + break; + default : + firstExpression = primaryExpression(scope, kind, key); + } + IASTExpression secondExpression = null; + for (;;) { + switch (LT(1)) { + case IToken.tLBRACKET : + // array access + consume(IToken.tLBRACKET); + if (templateIdScopes != null) { + templateIdScopes.push(new Integer(IToken.tLBRACKET)); + } + secondExpression = expression(scope, + CompletionKind.SINGLE_NAME_REFERENCE, key); + consume(IToken.tRBRACKET); + if (templateIdScopes != null) { + templateIdScopes.pop(); + } + try { + firstExpression = astFactory.createExpression(scope, + IASTExpression.Kind.POSTFIX_SUBSCRIPT, + firstExpression, secondExpression, null, null, + null, EMPTY_STRING, null); + } catch (ASTSemanticException e2) { + throwBacktrack(e2.getProblem()); + } catch (Exception e) { + logException( + "postfixExpression_3::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + break; + case IToken.tLPAREN : + // function call + consume(IToken.tLPAREN); + IASTNode context = null; + if (firstExpression != null) { + if (firstExpression.getExpressionKind() == IASTExpression.Kind.ID_EXPRESSION) + setCurrentFunctionName(firstExpression + .getIdExpression()); + else if (firstExpression.getRHSExpression() != null + && firstExpression.getRHSExpression() + .getIdExpression() != null) { + setCurrentFunctionName(firstExpression + .getRHSExpression().getIdExpression()); + context = astFactory + .expressionToMostPreciseASTNode(scope, + firstExpression.getLHSExpression()); + } + } + + if (templateIdScopes != null) { + templateIdScopes.push(new Integer(IToken.tLPAREN)); + } + setCompletionValues(scope, + CompletionKind.FUNCTION_REFERENCE, context); + secondExpression = expression(scope, + CompletionKind.FUNCTION_REFERENCE, key); + setCurrentFunctionName(EMPTY_STRING); + consume(IToken.tRPAREN); + if (templateIdScopes != null) { + templateIdScopes.pop(); + } + try { + firstExpression = astFactory.createExpression(scope, + IASTExpression.Kind.POSTFIX_FUNCTIONCALL, + firstExpression, secondExpression, null, null, + null, EMPTY_STRING, null); + } catch (ASTSemanticException e3) { + throwBacktrack(e3.getProblem()); + } catch (Exception e) { + logException( + "postfixExpression_4::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + break; + case IToken.tINCR : + consume(IToken.tINCR); + try { + firstExpression = astFactory.createExpression(scope, + IASTExpression.Kind.POSTFIX_INCREMENT, + firstExpression, null, null, null, null, + EMPTY_STRING, null); + } catch (ASTSemanticException e1) { + throwBacktrack(e1.getProblem()); + } catch (Exception e) { + logException( + "postfixExpression_5::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + break; + case IToken.tDECR : + consume(); + try { + firstExpression = astFactory.createExpression(scope, + IASTExpression.Kind.POSTFIX_DECREMENT, + firstExpression, null, null, null, null, + EMPTY_STRING, null); + } catch (ASTSemanticException e4) { + throwBacktrack(e4.getProblem()); + } catch (Exception e) { + logException( + "postfixExpression_6::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + break; + case IToken.tDOT : + // member access + consume(IToken.tDOT); + + if (queryLookaheadCapability()) + if (LT(1) == IToken.t_template) { + consume(IToken.t_template); + isTemplate = true; + } + + Kind memberCompletionKind = (isTemplate + ? IASTExpression.Kind.POSTFIX_DOT_TEMPL_IDEXPRESS + : IASTExpression.Kind.POSTFIX_DOT_IDEXPRESSION); + + setCompletionValues(scope, CompletionKind.MEMBER_REFERENCE, + KeywordSetKey.EMPTY, firstExpression, + memberCompletionKind); + secondExpression = primaryExpression(scope, + CompletionKind.MEMBER_REFERENCE, key); + if (secondExpression != null + && secondExpression.getExpressionKind() == Kind.ID_EXPRESSION + && secondExpression.getIdExpression().indexOf('~') != -1) + memberCompletionKind = Kind.POSTFIX_DOT_DESTRUCTOR; + + try { + firstExpression = astFactory.createExpression(scope, + memberCompletionKind, firstExpression, + secondExpression, null, null, null, + EMPTY_STRING, null); + } catch (ASTSemanticException e5) { + throwBacktrack(e5.getProblem()); + } catch (Exception e) { + logException( + "postfixExpression_7::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + break; + case IToken.tARROW : + // member access + consume(IToken.tARROW); + + if (queryLookaheadCapability()) + if (LT(1) == IToken.t_template) { + consume(IToken.t_template); + isTemplate = true; + } + + Kind arrowCompletionKind = (isTemplate + ? IASTExpression.Kind.POSTFIX_ARROW_TEMPL_IDEXP + : IASTExpression.Kind.POSTFIX_ARROW_IDEXPRESSION); + + setCompletionValues(scope, CompletionKind.MEMBER_REFERENCE, + KeywordSetKey.EMPTY, firstExpression, + arrowCompletionKind); + secondExpression = primaryExpression(scope, + CompletionKind.MEMBER_REFERENCE, key); + + if (secondExpression != null + && secondExpression.getExpressionKind() == Kind.ID_EXPRESSION + && secondExpression.getIdExpression().indexOf('~') != -1) + arrowCompletionKind = Kind.POSTFIX_ARROW_DESTRUCTOR; + try { + firstExpression = astFactory.createExpression(scope, + arrowCompletionKind, firstExpression, + secondExpression, null, null, null, + EMPTY_STRING, null); + } catch (ASTSemanticException e) { + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException( + "postfixExpression_8::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + break; + default : + return firstExpression; + } + } } /** * @return * @throws EndOfFileException */ - protected boolean queryLookaheadCapability(int count) throws EndOfFileException { + protected boolean queryLookaheadCapability(int count) + throws EndOfFileException { //make sure we can look ahead one before doing this boolean result = true; - try - { + try { LA(count); - } - catch( EndOfFileException olre ) - { + } catch (EndOfFileException olre) { result = false; } return result; @@ -2531,280 +2366,209 @@ public class ExpressionParser implements IExpressionParser, IParserData { LA(1); } - protected IASTExpression simpleTypeConstructorExpression(IASTScope scope, Kind type, KeywordSetKey key ) throws EndOfFileException, BacktrackException { - String typeName = consume().getImage(); - consume(IToken.tLPAREN); - setCurrentFunctionName( typeName ); - IASTExpression inside = expression(scope, CompletionKind.CONSTRUCTOR_REFERENCE, key); - setCurrentFunctionName( EMPTY_STRING ); - consume(IToken.tRPAREN); - try - { - return astFactory.createExpression( - scope, - type, - inside, - null, - null, - null, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e) - { - failParse(); - throw backtrack; - } catch (Exception e) - { - logException( "simpleTypeConstructorExpression::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } + protected IASTExpression simpleTypeConstructorExpression(IASTScope scope, + Kind type, KeywordSetKey key) throws EndOfFileException, + BacktrackException { + int startingOffset = LA(1).getOffset(); + String typeName = consume().getImage(); + consume(IToken.tLPAREN); + setCurrentFunctionName(typeName); + IASTExpression inside = expression(scope, + CompletionKind.CONSTRUCTOR_REFERENCE, key); + setCurrentFunctionName(EMPTY_STRING); + consume(IToken.tRPAREN); + try { + return astFactory.createExpression(scope, type, inside, null, null, + null, null, EMPTY_STRING, null); + } catch (ASTSemanticException e) { + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException( + "simpleTypeConstructorExpression::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + return null; } /** * @param expression * @throws BacktrackException */ - protected IASTExpression primaryExpression(IASTScope scope, CompletionKind kind, KeywordSetKey key) throws EndOfFileException, BacktrackException { - IToken t = null; - switch (LT(1)) - { - // TO DO: we need more literals... - case IToken.tINTEGER : - t = consume(); - try - { - return astFactory.createExpression( scope, IASTExpression.Kind.PRIMARY_INTEGER_LITERAL, null, null, null, null, null, t.getImage(), null ); - } - catch (ASTSemanticException e1) - { - throw backtrack; - } catch (Exception e) - { - logException( "primaryExpression_1::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - case IToken.tFLOATINGPT : - t = consume(); - try - { - return astFactory.createExpression( - scope, - IASTExpression.Kind.PRIMARY_FLOAT_LITERAL, - null, - null, - null, - null, - null, t.getImage(), null); - } - catch (ASTSemanticException e2) - { - throw backtrack; - } catch (Exception e) - { - logException( "primaryExpression_2::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - case IToken.tSTRING : - case IToken.tLSTRING : + protected IASTExpression primaryExpression(IASTScope scope, + CompletionKind kind, KeywordSetKey key) throws EndOfFileException, + BacktrackException { + IToken t = null; + switch (LT(1)) { + // TO DO: we need more literals... + case IToken.tINTEGER : t = consume(); - try - { - return astFactory.createExpression( scope, IASTExpression.Kind.PRIMARY_STRING_LITERAL, null, null, null, null, null, t.getImage(), null ); - } - catch (ASTSemanticException e5) - { - throw backtrack; - } catch (Exception e) - { - logException( "primaryExpression_3::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - - case IToken.t_false : - case IToken.t_true : - t = consume(); - try - { - return astFactory.createExpression( - scope, - IASTExpression.Kind.PRIMARY_BOOLEAN_LITERAL, - null, - null, - null, - null, - null, t.getImage(), null); - } - catch (ASTSemanticException e3) - { - throw backtrack; - } catch (Exception e) - { - logException( "primaryExpression_4::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - - case IToken.tCHAR : + try { + return astFactory.createExpression(scope, + IASTExpression.Kind.PRIMARY_INTEGER_LITERAL, null, + null, null, null, null, t.getImage(), null); + } catch (ASTSemanticException e1) { + throwBacktrack(e1.getProblem()); + } catch (Exception e) { + logException("primaryExpression_1::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(t.getOffset()); + } + case IToken.tFLOATINGPT : + t = consume(); + try { + return astFactory.createExpression(scope, + IASTExpression.Kind.PRIMARY_FLOAT_LITERAL, null, + null, null, null, null, t.getImage(), null); + } catch (ASTSemanticException e2) { + throwBacktrack(e2.getProblem()); + } catch (Exception e) { + logException("primaryExpression_2::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(t.getOffset()); + } + case IToken.tSTRING : + case IToken.tLSTRING : + t = consume(); + try { + return astFactory.createExpression(scope, + IASTExpression.Kind.PRIMARY_STRING_LITERAL, null, + null, null, null, null, t.getImage(), null); + } catch (ASTSemanticException e5) { + throwBacktrack(e5.getProblem()); + } catch (Exception e) { + logException("primaryExpression_3::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(t.getOffset()); + } + + case IToken.t_false : + case IToken.t_true : + t = consume(); + try { + return astFactory.createExpression(scope, + IASTExpression.Kind.PRIMARY_BOOLEAN_LITERAL, null, + null, null, null, null, t.getImage(), null); + } catch (ASTSemanticException e3) { + throwBacktrack(e3.getProblem()); + } catch (Exception e) { + logException("primaryExpression_4::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(t.getOffset()); + } + + case IToken.tCHAR : case IToken.tLCHAR : - - t = consume(); - try - { - return astFactory.createExpression( - scope, - IASTExpression.Kind.PRIMARY_CHAR_LITERAL, - null, - null, - null, - null, - null, t.getImage(), null); - } - catch (ASTSemanticException e4) - { - throw backtrack; - } catch (Exception e) - { - logException( "primaryExpression_5::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - - case IToken.t_this : - consume(IToken.t_this); - try - { - return astFactory.createExpression( - scope, - IASTExpression.Kind.PRIMARY_THIS, - null, - null, - null, - null, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e7) - { - throw backtrack; - } catch (Exception e) - { - logException( "primaryExpression_6::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - case IToken.tLPAREN : - consume(); - if( templateIdScopes != null ){ templateIdScopes.push( new Integer( IToken.tLPAREN ) ); } - IASTExpression lhs = expression(scope, kind, key); - consume(IToken.tRPAREN); - if( templateIdScopes != null ){ templateIdScopes.pop(); } - try - { - return astFactory.createExpression( - scope, - IASTExpression.Kind.PRIMARY_BRACKETED_EXPRESSION, - lhs, - null, - null, - null, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e6) - { - throw backtrack; - } catch (Exception e) - { - logException( "primaryExpression_7::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - case IToken.tIDENTIFIER : - case IToken.tCOLONCOLON : - case IToken.t_operator : - case IToken.tCOMPL: - ITokenDuple duple = null; - - - try - { + + t = consume(); + try { + return astFactory.createExpression(scope, + IASTExpression.Kind.PRIMARY_CHAR_LITERAL, null, + null, null, null, null, t.getImage(), null); + } catch (ASTSemanticException e4) { + throwBacktrack(e4.getProblem()); + } catch (Exception e) { + logException("primaryExpression_5::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(t.getOffset()); + } + + case IToken.t_this : + t = consume(IToken.t_this); + try { + return astFactory.createExpression(scope, + IASTExpression.Kind.PRIMARY_THIS, null, null, null, + null, null, EMPTY_STRING, null); + } catch (ASTSemanticException e7) { + throwBacktrack(e7.getProblem()); + } catch (Exception e) { + logException("primaryExpression_6::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(t.getOffset()); + } + case IToken.tLPAREN : + t = consume(); + if (templateIdScopes != null) { + templateIdScopes.push(new Integer(IToken.tLPAREN)); + } + IASTExpression lhs = expression(scope, kind, key); + consume(IToken.tRPAREN); + if (templateIdScopes != null) { + templateIdScopes.pop(); + } + try { + return astFactory.createExpression(scope, + IASTExpression.Kind.PRIMARY_BRACKETED_EXPRESSION, + lhs, null, null, null, null, EMPTY_STRING, null); + } catch (ASTSemanticException e6) { + throwBacktrack(e6.getProblem()); + } catch (Exception e) { + logException("primaryExpression_7::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(t.getOffset()); + } + case IToken.tIDENTIFIER : + case IToken.tCOLONCOLON : + case IToken.t_operator : + case IToken.tCOMPL : + ITokenDuple duple = null; + int startingOffset = LA(1).getOffset(); + try { duple = name(scope, kind, key); - } - catch( BacktrackException bt ) - { - IToken mark = mark(); - Declarator d = new Declarator( new DeclarationWrapper(scope, mark.getOffset(), mark.getLineNumber(), null) ); - - if (LT(1) == IToken.tCOLONCOLON || LT(1) == IToken.tIDENTIFIER) - { + } catch (BacktrackException bt) { + IToken mark = mark(); + Declarator d = new Declarator(new DeclarationWrapper(scope, + mark.getOffset(), mark.getLineNumber(), null)); + + if (LT(1) == IToken.tCOLONCOLON + || LT(1) == IToken.tIDENTIFIER) { IToken start = consume(); IToken end = null; if (start.getType() == IToken.tIDENTIFIER) - end = consumeTemplateParameters(end); - while (LT(1) == IToken.tCOLONCOLON || LT(1) == IToken.tIDENTIFIER) - { - end = consume(); - if (end.getType() == IToken.tIDENTIFIER) - end = consumeTemplateParameters(end); + end = consumeTemplateParameters(end); + while (LT(1) == IToken.tCOLONCOLON + || LT(1) == IToken.tIDENTIFIER) { + end = consume(); + if (end.getType() == IToken.tIDENTIFIER) + end = consumeTemplateParameters(end); } if (LT(1) == IToken.t_operator) operatorId(d, start, null, kind); - else - { - backup(mark); - throw backtrack; + else { + backup(mark); + throwBacktrack(startingOffset); } - } - else if( LT(1) == IToken.t_operator ) - operatorId( d, null, null, kind); - - duple = d.getNameDuple(); - } - - try - { - return astFactory.createExpression( - scope, - IASTExpression.Kind.ID_EXPRESSION, - null, - null, - null, - null, - duple, EMPTY_STRING, null); - } - catch (ASTSemanticException e8) - { - throw backtrack; - } catch (Exception e) - { - logException( "primaryExpression_8::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } - default : - if( !queryLookaheadCapability(2) ) - { - if( LA(1).canBeAPrefix() ) - { - consume(); - checkEndOfFile(); - } - } + } else if (LT(1) == IToken.t_operator) + operatorId(d, null, null, kind); + + duple = d.getNameDuple(); + } + + try { + return astFactory.createExpression(scope, + IASTExpression.Kind.ID_EXPRESSION, null, null, + null, null, duple, EMPTY_STRING, null); + } catch (ASTSemanticException e8) { + throwBacktrack(e8.getProblem()); + } catch (Exception e) { + logException("primaryExpression_8::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + default : + startingOffset = LA(1).getOffset(); + if (!queryLookaheadCapability(2)) { + if (LA(1).canBeAPrefix()) { + consume(); + checkEndOfFile(); + } + } IASTExpression empty = null; - try { - empty = astFactory.createExpression( - scope, - IASTExpression.Kind.PRIMARY_EMPTY, - null, - null, - null, - null, - null, EMPTY_STRING, null); + try { + empty = astFactory.createExpression(scope, + IASTExpression.Kind.PRIMARY_EMPTY, null, null, + null, null, null, EMPTY_STRING, null); } catch (ASTSemanticException e9) { - // TODO Auto-generated catch block - e9.printStackTrace(); - - } catch( Exception e ) - { - logException( "primaryExpression_9::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; + throwBacktrack( e9.getProblem() ); + return null; + } catch (Exception e) { + logException("primaryExpression_9::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); } return empty; - } - + } + } /** @@ -2814,26 +2578,24 @@ public class ExpressionParser implements IExpressionParser, IParserData { * @throws EndOfFileException thrown when the scanner.nextToken() yields no tokens */ protected IToken fetchToken() throws EndOfFileException { - if(limitReached) throw new EndOfFileException(); - - try - { - IToken value = scanner.nextToken(); - return value; - } - catch( OffsetLimitReachedException olre ) - { - limitReached = true; - handleOffsetLimitException(olre); - return null; - } - catch (ScannerException e) - { - TraceUtil.outputTrace(log, "ScannerException thrown : ", e.getProblem(), null, null, null); //$NON-NLS-1$ - log.errorLog( "Scanner Exception: " + e.getProblem().getMessage()); //$NON-NLS-1$ - failParse(); - return fetchToken(); - } + if (limitReached) + throw new EndOfFileException(); + + try { + IToken value = scanner.nextToken(); + return value; + } catch (OffsetLimitReachedException olre) { + limitReached = true; + handleOffsetLimitException(olre); + return null; + } catch (ScannerException e) { + TraceUtil + .outputTrace( + log, + "ScannerException thrown : ", e.getProblem(), null, null, null); //$NON-NLS-1$ + log.errorLog("Scanner Exception: " + e.getProblem().getMessage()); //$NON-NLS-1$ + return fetchToken(); + } } /** @@ -2842,106 +2604,98 @@ public class ExpressionParser implements IExpressionParser, IParserData { protected void handleNewToken(IToken value) { } - protected void handleOffsetLimitException(OffsetLimitReachedException exception) throws EndOfFileException { + protected void handleOffsetLimitException( + OffsetLimitReachedException exception) throws EndOfFileException { // unexpected, throw EOF instead (equivalent) throw new EndOfFileException(); } - protected IASTExpression assignmentOperatorExpression(IASTScope scope, IASTExpression.Kind kind, IASTExpression lhs, CompletionKind completionKind, KeywordSetKey key) throws EndOfFileException, BacktrackException { - consume(); - IASTExpression assignmentExpression = assignmentExpression(scope,completionKind, key); - - try - { - return astFactory.createExpression( - scope, - kind, - lhs, - assignmentExpression, - null, - null, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e) - { - throw backtrack; - } catch (Exception e) - { - logException( "assignmentOperatorExpression::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } + protected IASTExpression assignmentOperatorExpression(IASTScope scope, + IASTExpression.Kind kind, IASTExpression lhs, + CompletionKind completionKind, KeywordSetKey key) + throws EndOfFileException, BacktrackException { + IToken t = consume(); + IASTExpression assignmentExpression = assignmentExpression(scope, + completionKind, key); + + try { + return astFactory.createExpression(scope, kind, lhs, + assignmentExpression, null, null, null, EMPTY_STRING, null); + } catch (ASTSemanticException e) { + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException("assignmentOperatorExpression::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(t.getOffset()); + } + return null; } - protected void setCompletionValues(IASTScope scope, IASTCompletionNode.CompletionKind kind, KeywordSetKey key) throws EndOfFileException { + protected void setCompletionValues(IASTScope scope, + IASTCompletionNode.CompletionKind kind, KeywordSetKey key) + throws EndOfFileException { } - protected void setCompletionValues(IASTScope scope, IASTCompletionNode.CompletionKind kind, KeywordSetKey key, IASTNode node, String prefix) throws EndOfFileException { + protected void setCompletionValues(IASTScope scope, + IASTCompletionNode.CompletionKind kind, KeywordSetKey key, + IASTNode node, String prefix) throws EndOfFileException { } - protected void setCompletionValues(IASTScope scope, CompletionKind kind, KeywordSetKey key, IASTExpression firstExpression, Kind expressionKind) throws EndOfFileException { - } - - protected void setCompletionValues( IASTScope scope, CompletionKind kind, IToken first, IToken last, KeywordSetKey key ) throws EndOfFileException { + protected void setCompletionValues(IASTScope scope, CompletionKind kind, + KeywordSetKey key, IASTExpression firstExpression, + Kind expressionKind) throws EndOfFileException { } - - protected IASTExpression unaryOperatorCastExpression(IASTScope scope, IASTExpression.Kind kind, CompletionKind completionKind, KeywordSetKey key) throws EndOfFileException, BacktrackException { - IASTExpression castExpression = castExpression(scope,completionKind,key); - try - { - return astFactory.createExpression( - scope, - kind, - castExpression, - null, - null, - null, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e) - { - throw backtrack; - } catch (Exception e) - { - logException( "unaryOperatorCastExpression::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } + protected void setCompletionValues(IASTScope scope, CompletionKind kind, + IToken first, IToken last, KeywordSetKey key) + throws EndOfFileException { } - protected IASTExpression specialCastExpression(IASTScope scope, IASTExpression.Kind kind, KeywordSetKey key) throws EndOfFileException, BacktrackException { - consume(); - consume(IToken.tLT); - IASTTypeId duple = typeId(scope, false, CompletionKind.TYPE_REFERENCE); - consume(IToken.tGT); - consume(IToken.tLPAREN); - IASTExpression lhs = expression(scope, CompletionKind.SINGLE_NAME_REFERENCE, key); - consume(IToken.tRPAREN); - try - { - return astFactory.createExpression( - scope, - kind, - lhs, - null, - null, - duple, - null, EMPTY_STRING, null); - } - catch (ASTSemanticException e) - { - throw backtrack; - } catch (Exception e) - { - logException( "specialCastExpression::createExpression()", e ); //$NON-NLS-1$ - throw backtrack; - } + protected IASTExpression unaryOperatorCastExpression(IASTScope scope, + IASTExpression.Kind kind, CompletionKind completionKind, + KeywordSetKey key) throws EndOfFileException, BacktrackException { + int startingOffset = LA(1).getOffset(); + IASTExpression castExpression = castExpression(scope, completionKind, + key); + try { + return astFactory.createExpression(scope, kind, castExpression, + null, null, null, null, EMPTY_STRING, null); + } catch (ASTSemanticException e) { + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException("unaryOperatorCastExpression::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + return null; + } + + protected IASTExpression specialCastExpression(IASTScope scope, + IASTExpression.Kind kind, KeywordSetKey key) + throws EndOfFileException, BacktrackException { + int startingOffset = consume().getOffset(); + consume(IToken.tLT); + IASTTypeId duple = typeId(scope, false, CompletionKind.TYPE_REFERENCE); + consume(IToken.tGT); + consume(IToken.tLPAREN); + IASTExpression lhs = expression(scope, + CompletionKind.SINGLE_NAME_REFERENCE, key); + consume(IToken.tRPAREN); + try { + return astFactory.createExpression(scope, kind, lhs, null, null, + duple, null, EMPTY_STRING, null); + } catch (ASTSemanticException e) { + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException("specialCastExpression::createExpression()", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + return null; } public char[] getCurrentFilename() { return scanner.getCurrentFilename(); } - - protected boolean parserTimeout(){ + + protected boolean parserTimeout() { return false; } /* (non-Javadoc) @@ -2978,17 +2732,29 @@ public class ExpressionParser implements IExpressionParser, IParserData { public String getFilenameForIndex(int index) { return scanner.getFilenameForIndex(index); } - - public boolean validateCaches() - { + + public boolean validateCaches() { return true; } - - + /* (non-Javadoc) * @see java.lang.Object#toString() */ public String toString() { return scanner.toString(); //$NON-NLS-1$ } -} + + /** + * @return Returns the backtrackCount. + */ + public final int getBacktrackCount() { + return backtrackCount; + } + + /** + * @param bt + */ + protected void throwBacktrack(BacktrackException bt) throws BacktrackException { + throw bt; + } +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java index 86f712e7faf..df6e3185171 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java @@ -64,8 +64,8 @@ import org.eclipse.cdt.internal.core.parser.problem.IProblemFactory; import org.eclipse.cdt.internal.core.parser.token.TokenFactory; /** - * This is our first implementation of the IParser interface, serving as a parser for - * ANSI C and C++. + * This is our first implementation of the IParser interface, serving as a + * parser for ANSI C and C++. * * From time to time we will make reference to the ANSI ISO specifications. * @@ -77,10 +77,10 @@ public abstract class Parser extends ExpressionParser implements IParser protected ISourceElementRequestor requestor = null; private IProblemFactory problemFactory = new ParserProblemFactory(); /** - * This is the standard cosntructor that we expect the Parser to be instantiated - * with. - * - */ + * This is the standard cosntructor that we expect the Parser to be + * instantiated with. + * + */ public Parser( IScanner scanner, ISourceElementRequestor callback, @@ -93,47 +93,59 @@ public abstract class Parser extends ExpressionParser implements IParser - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see org.eclipse.cdt.internal.core.parser.ExpressionParser#failParse() */ - protected void failParse() { - IToken referenceToken = null; - if( lastToken != null ) - referenceToken = lastToken; + protected void failParse( BacktrackException bt ) { + if( bt.getProblem() == null ) + { + IToken referenceToken = null; + if( lastToken != null ) + referenceToken = lastToken; + else + try + { + referenceToken = LA(1); + } + catch( EndOfFileException eof ) + { + return; + } + + IProblem problem = problemFactory.createProblem( + IProblem.SYNTAX_ERROR, + bt.getStartingOffset(), + referenceToken.getOffset(), + referenceToken.getLineNumber(), + scanner.getCurrentFilename(), + EMPTY_STRING, + false, + true ); + requestor.acceptProblem( problem ); + } else - try - { - referenceToken = LA(1); - } - catch( EndOfFileException eof ) - { - return; - } - IProblem problem = problemFactory.createProblem( - IProblem.SYNTAX_ERROR, - referenceToken.getOffset(), - referenceToken.getOffset(), - referenceToken.getLineNumber(), - scanner.getCurrentFilename(), - EMPTY_STRING, - false, - true ); - requestor.acceptProblem( problem ); + { + requestor.acceptProblem( bt.getProblem() ); + } super.failParse(); } // counter that keeps track of the number of times Parser.parse() is called private static int parseCount = 0; - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser.IParser#parse() - */ + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser.IParser#parse() + */ public boolean parse() { long startTime = System.currentTimeMillis(); translationUnit(); // For the debuglog to take place, you have to call // Util.setDebugging(true); - // Or set debug to true in the core plugin preference + // Or set debug to true in the core plugin preference log.traceLog( "Parse " //$NON-NLS-1$ + (++parseCount) @@ -146,10 +158,10 @@ public abstract class Parser extends ExpressionParser implements IParser /** - * This is the top-level entry point into the ANSI C++ grammar. - * - * translationUnit : (declaration)* - */ + * This is the top-level entry point into the ANSI C++ grammar. + * + * translationUnit : (declaration)* + */ protected void translationUnit() { try @@ -191,7 +203,7 @@ public abstract class Parser extends ExpressionParser implements IParser try { // Mark as failure and try to reach a recovery point - failParse(); + failParse(b); if (lastBacktrack != -1 && lastBacktrack == LA(1).hashCode()) { // we haven't progressed from the last backtrack @@ -251,11 +263,14 @@ public abstract class Parser extends ExpressionParser implements IParser /** - * This function is called whenever we encounter and error that we cannot backtrack out of and we - * still wish to try and continue on with the parse to do a best-effort parse for our client. - * - * @throws EndOfFileException We can potentially hit EndOfFile here as we are skipping ahead. - */ + * This function is called whenever we encounter and error that we cannot + * backtrack out of and we still wish to try and continue on with the parse + * to do a best-effort parse for our client. + * + * @throws EndOfFileException + * We can potentially hit EndOfFile here as we are skipping + * ahead. + */ protected void errorHandling() throws EndOfFileException { failParse(); @@ -282,18 +297,19 @@ public abstract class Parser extends ExpressionParser implements IParser consume(); } /** - * The merger of using-declaration and using-directive in ANSI C++ grammar. - * - * using-declaration: - * using typename? ::? nested-name-specifier unqualified-id ; - * using :: unqualified-id ; - * using-directive: - * using namespace ::? nested-name-specifier? namespace-name ; - * - * @param container Callback object representing the scope these definitions fall into. - * @return TODO - * @throws BacktrackException request for a backtrack - */ + * The merger of using-declaration and using-directive in ANSI C++ grammar. + * + * using-declaration: using typename? ::? nested-name-specifier + * unqualified-id ; using :: unqualified-id ; using-directive: using + * namespace ::? nested-name-specifier? namespace-name ; + * + * @param container + * Callback object representing the scope these definitions fall + * into. + * @return TODO + * @throws BacktrackException + * request for a backtrack + */ protected IASTDeclaration usingClause(IASTScope scope) throws EndOfFileException, BacktrackException { @@ -311,7 +327,7 @@ public abstract class Parser extends ExpressionParser implements IParser if (LT(1) == IToken.tIDENTIFIER || LT(1) == IToken.tCOLONCOLON) duple = name(scope, CompletionKind.NAMESPACE_REFERENCE, KeywordSetKey.EMPTY); else - throw backtrack; + throwBacktrack(firstToken.getOffset()); if (LT(1) == IToken.tSEMI) { IToken last = consume(IToken.tSEMI); @@ -324,12 +340,12 @@ public abstract class Parser extends ExpressionParser implements IParser catch (Exception e1) { logException( "usingClause:createUsingDirective", e1 ); //$NON-NLS-1$ - throw backtrack; + throwBacktrack(firstToken.getOffset()); } astUD.acceptElement(requestor, astFactory.getReferenceManager()); return astUD; } - throw backtrack; + throwBacktrack(firstToken.getOffset()); } boolean typeName = false; setCompletionValues(scope, CompletionKind.TYPE_REFERENCE, KeywordSetKey.POST_USING ); @@ -349,7 +365,7 @@ public abstract class Parser extends ExpressionParser implements IParser } else { - throw backtrack; + throwBacktrack(firstToken.getOffset()); } if (LT(1) == IToken.tSEMI) { @@ -368,38 +384,40 @@ public abstract class Parser extends ExpressionParser implements IParser catch (Exception e1) { logException( "usingClause:createUsingDeclaration", e1 ); //$NON-NLS-1$ - throw backtrack; + throwBacktrack(firstToken.getOffset()); } declaration.acceptElement( requestor, astFactory.getReferenceManager() ); setCompletionValues(scope, getCompletionKindForDeclaration(scope, null), KeywordSetKey.DECLARATION ); return declaration; } - throw backtrack; - + throwBacktrack(firstToken.getOffset()); + return null; } /** - * Implements Linkage specification in the ANSI C++ grammar. - * - * linkageSpecification - * : extern "string literal" declaration - * | extern "string literal" { declaration-seq } - * - * @param container Callback object representing the scope these definitions fall into. - * @return TODO - * @throws BacktrackException request for a backtrack - */ + * Implements Linkage specification in the ANSI C++ grammar. + * + * linkageSpecification : extern "string literal" declaration | extern + * "string literal" { declaration-seq } + * + * @param container + * Callback object representing the scope these definitions fall + * into. + * @return TODO + * @throws BacktrackException + * request for a backtrack + */ protected IASTDeclaration linkageSpecification(IASTScope scope) throws EndOfFileException, BacktrackException { IToken firstToken = consume(IToken.t_extern); if (LT(1) != IToken.tSTRING) - throw backtrack; + throwBacktrack(firstToken.getOffset()); IToken spec = consume(IToken.tSTRING); if (LT(1) == IToken.tLBRACE) { consume(IToken.tLBRACE); - IASTLinkageSpecification linkage; + IASTLinkageSpecification linkage = null; try { linkage = @@ -411,7 +429,7 @@ public abstract class Parser extends ExpressionParser implements IParser catch (Exception e) { logException( "linkageSpecification_1:createLinkageSpecification", e ); //$NON-NLS-1$ - throw backtrack; + throwBacktrack(firstToken.getOffset()); } linkage.enterScope( requestor, astFactory.getReferenceManager() ); @@ -430,7 +448,7 @@ public abstract class Parser extends ExpressionParser implements IParser } catch (BacktrackException bt) { - failParse(); + failParse(bt); if (checkToken == LA(1).hashCode()) errorHandling(); } @@ -458,7 +476,8 @@ public abstract class Parser extends ExpressionParser implements IParser catch (Exception e) { logException( "linkageSpecification_2:createLinkageSpecification", e ); //$NON-NLS-1$ - throw backtrack; + throwBacktrack(firstToken.getOffset()); + return null; } linkage.enterScope( requestor, astFactory.getReferenceManager() ); declaration(linkage, null, null, KeywordSetKey.DECLARATION); @@ -467,18 +486,21 @@ public abstract class Parser extends ExpressionParser implements IParser } /** - * - * Represents the emalgamation of template declarations, template instantiations and - * specializations in the ANSI C++ grammar. - * - * template-declaration: export? template < template-parameter-list > declaration - * explicit-instantiation: template declaration - * explicit-specialization: template <> declaration - * - * @param container Callback object representing the scope these definitions fall into. - * @return TODO - * @throws BacktrackException request for a backtrack - */ + * + * Represents the emalgamation of template declarations, template + * instantiations and specializations in the ANSI C++ grammar. + * + * template-declaration: export? template < template-parameter-list > + * declaration explicit-instantiation: template declaration + * explicit-specialization: template <>declaration + * + * @param container + * Callback object representing the scope these definitions fall + * into. + * @return TODO + * @throws BacktrackException + * request for a backtrack + */ protected IASTDeclaration templateDeclaration(IASTScope scope) throws EndOfFileException, BacktrackException { @@ -508,7 +530,8 @@ public abstract class Parser extends ExpressionParser implements IParser { logException( "templateDeclaration:createTemplateInstantiation", e ); //$NON-NLS-1$ backup( mark ); - throw backtrack; + throwBacktrack(firstToken.getOffset()); + return null; } templateInstantiation.enterScope( requestor, astFactory.getReferenceManager() ); declaration(templateInstantiation, templateInstantiation, null, KeywordSetKey.DECLARATION); @@ -535,7 +558,8 @@ public abstract class Parser extends ExpressionParser implements IParser { logException( "templateDeclaration:createTemplateSpecialization", e ); //$NON-NLS-1$ backup( mark ); - throw backtrack; + throwBacktrack(firstToken.getOffset()); + return null; } templateSpecialization.enterScope(requestor, astFactory.getReferenceManager()); declaration(templateSpecialization, templateSpecialization, null, KeywordSetKey.DECLARATION); @@ -563,7 +587,8 @@ public abstract class Parser extends ExpressionParser implements IParser catch (Exception e) { logException( "templateDeclaration:createTemplateDeclaration", e ); //$NON-NLS-1$ - throw backtrack; + throwBacktrack(firstToken.getOffset()); + return null; } templateDecl.enterScope( requestor, astFactory.getReferenceManager() ); try{ @@ -584,30 +609,26 @@ public abstract class Parser extends ExpressionParser implements IParser } } /** - * - * - * - * template-parameter-list: template-parameter - * template-parameter-list , template-parameter - * template-parameter: type-parameter - * parameter-declaration - * type-parameter: class identifier? - * class identifier? = type-id - * typename identifier? - * typename identifier? = type-id - * template < template-parameter-list > class identifier? - * template < template-parameter-list > class identifier? = id-expression - * template-id: template-name < template-argument-list?> - * template-name: identifier - * template-argument-list: template-argument - * template-argument-list , template-argument - * template-argument: assignment-expression - * type-id - * id-expression - * - * @param templateDeclaration Callback's templateDeclaration which serves as a scope to this list. - * @throws BacktrackException request for a backtrack - */ + * + * + * + * template-parameter-list: template-parameter template-parameter-list , + * template-parameter template-parameter: type-parameter + * parameter-declaration type-parameter: class identifier? class identifier? = + * type-id typename identifier? typename identifier? = type-id template < + * template-parameter-list > class identifier? template < + * template-parameter-list > class identifier? = id-expression template-id: + * template-name < template-argument-list?> template-name: identifier + * template-argument-list: template-argument template-argument-list , + * template-argument template-argument: assignment-expression type-id + * id-expression + * + * @param templateDeclaration + * Callback's templateDeclaration which serves as a scope to this + * list. + * @throws BacktrackException + * request for a backtrack + */ protected List templateParameterList(IASTScope scope) throws BacktrackException, EndOfFileException { @@ -619,6 +640,7 @@ public abstract class Parser extends ExpressionParser implements IParser if( parameterScope == null ) parameterScope = scope; + int startingOffset = LA(1).getOffset(); for (;;) { if (LT(1) == IToken.tGT) @@ -668,7 +690,7 @@ public abstract class Parser extends ExpressionParser implements IParser catch (Exception e) { logException( "templateParameterList_1:createTemplateParameter", e ); //$NON-NLS-1$ - throw backtrack; + throwBacktrack(startingOffset); } } @@ -714,7 +736,7 @@ public abstract class Parser extends ExpressionParser implements IParser catch (Exception e) { logException( "templateParameterList_2:createTemplateParameter", e ); //$NON-NLS-1$ - throw backtrack; + throwBacktrack(startingOffset); } } else if (LT(1) == IToken.tCOMMA) @@ -756,35 +778,33 @@ public abstract class Parser extends ExpressionParser implements IParser catch (Exception e) { logException( "templateParameterList:createParameterDeclaration", e ); //$NON-NLS-1$ - throw backtrack; + throwBacktrack(startingOffset); } } } } /** - * The most abstract construct within a translationUnit : a declaration. - * - * declaration - * : {"asm"} asmDefinition - * | {"namespace"} namespaceDefinition - * | {"using"} usingDeclaration - * | {"export"|"template"} templateDeclaration - * | {"extern"} linkageSpecification - * | simpleDeclaration - * - * Notes: - * - folded in blockDeclaration - * - merged alternatives that required same LA - * - functionDefinition into simpleDeclaration - * - namespaceAliasDefinition into namespaceDefinition - * - usingDirective into usingDeclaration - * - explicitInstantiation and explicitSpecialization into - * templateDeclaration - * @param overideKey TODO - * @param container IParserCallback object which serves as the owner scope for this declaration. - * - * @throws BacktrackException request a backtrack - */ + * The most abstract construct within a translationUnit : a declaration. + * + * declaration : {"asm"} asmDefinition | {"namespace"} namespaceDefinition | + * {"using"} usingDeclaration | {"export"|"template"} templateDeclaration | + * {"extern"} linkageSpecification | simpleDeclaration + * + * Notes: - folded in blockDeclaration - merged alternatives that required + * same LA - functionDefinition into simpleDeclaration - + * namespaceAliasDefinition into namespaceDefinition - usingDirective into + * usingDeclaration - explicitInstantiation and explicitSpecialization into + * templateDeclaration + * + * @param overideKey + * TODO + * @param container + * IParserCallback object which serves as the owner scope for + * this declaration. + * + * @throws BacktrackException + * request a backtrack + */ protected void declaration( IASTScope scope, IASTTemplate ownerTemplate, CompletionKind overideKind, KeywordSetKey overideKey) @@ -816,9 +836,9 @@ public abstract class Parser extends ExpressionParser implements IParser catch (Exception e) { logException( "declaration:createASMDefinition", e ); //$NON-NLS-1$ - throw backtrack; + throwBacktrack(first.getOffset()); } - // if we made it this far, then we have all we need + // if we made it this far, then we have all we need // do the callback resultDeclaration.acceptElement(requestor, astFactory.getReferenceManager()); setCompletionValues(scope, kind, KeywordSetKey.DECLARATION ); @@ -871,8 +891,8 @@ public abstract class Parser extends ExpressionParser implements IParser catch (BacktrackException bt) { if( simpleDeclarationMark == null ) - throw backtrack; - // did not work + throwBacktrack( bt ); + // did not work backup(simpleDeclarationMark); try @@ -885,7 +905,7 @@ public abstract class Parser extends ExpressionParser implements IParser catch( BacktrackException bt2 ) { if( simpleDeclarationMark == null ) - throw backtrack; + throwBacktrack(bt2); backup( simpleDeclarationMark ); @@ -898,24 +918,28 @@ public abstract class Parser extends ExpressionParser implements IParser } catch( BacktrackException b3 ) { - backup( simpleDeclarationMark ); - throw b3; + backup( simpleDeclarationMark ); //TODO - necessary? + throwBacktrack( b3 ); + return null; } } + } } /** - * Serves as the namespace declaration portion of the ANSI C++ grammar. - * - * namespace-definition: - * namespace identifier { namespace-body } | namespace { namespace-body } - * namespace-body: - * declaration-seq? - * @param container IParserCallback object which serves as the owner scope for this declaration. - * @return TODO - * @throws BacktrackException request a backtrack - - */ + * Serves as the namespace declaration portion of the ANSI C++ grammar. + * + * namespace-definition: namespace identifier { namespace-body } | namespace { + * namespace-body } namespace-body: declaration-seq? + * + * @param container + * IParserCallback object which serves as the owner scope for + * this declaration. + * @return TODO + * @throws BacktrackException + * request a backtrack + * + */ protected IASTDeclaration namespaceDefinition(IASTScope scope) throws BacktrackException, EndOfFileException { @@ -925,7 +949,7 @@ public abstract class Parser extends ExpressionParser implements IParser setCompletionValues(scope,CompletionKind.NAMESPACE_REFERENCE, KeywordSetKey.EMPTY ); IToken identifier = null; - // optional name + // optional name if (LT(1) == IToken.tIDENTIFIER) identifier = identifier(); @@ -948,7 +972,8 @@ public abstract class Parser extends ExpressionParser implements IParser catch (Exception e1) { logException( "namespaceDefinition:createNamespaceDefinition", e1 ); //$NON-NLS-1$ - throw backtrack; + throwBacktrack(first.getOffset()); + return null; } namespaceDefinition.enterScope( requestor, astFactory.getReferenceManager() ); setCompletionValues(scope,CompletionKind.VARIABLE_TYPE, KeywordSetKey.DECLARATION ); @@ -968,7 +993,7 @@ public abstract class Parser extends ExpressionParser implements IParser } catch (BacktrackException bt) { - failParse(); + failParse(bt); if (checkToken == LA(1).hashCode()) errorHandling(); } @@ -992,7 +1017,10 @@ public abstract class Parser extends ExpressionParser implements IParser consume( IToken.tASSIGN ); if( identifier == null ) - throw backtrack; + { + throwBacktrack(first.getOffset()); + return null; + } ITokenDuple duple = name(scope, CompletionKind.NAMESPACE_REFERENCE, KeywordSetKey.EMPTY); consume( IToken.tSEMI ); @@ -1007,33 +1035,38 @@ public abstract class Parser extends ExpressionParser implements IParser catch (Exception e1) { logException( "namespaceDefinition:createNamespaceAlias", e1 ); //$NON-NLS-1$ - throw backtrack; + throwBacktrack(first.getOffset()); + return null; } return alias; } else { - throw backtrack; + throwBacktrack(first.getOffset()); + return null; } } /** - * Serves as the catch-all for all complicated declarations, including function-definitions. - * - * simpleDeclaration - * : (declSpecifier)* (initDeclarator ("," initDeclarator)*)? - * (";" | { functionBody } - * - * Notes: - * - append functionDefinition stuff to end of this rule - * - * To do: - * - work in functionTryBlock - * - * @param container IParserCallback object which serves as the owner scope for this declaration. - * @param tryConstructor true == take strategy1 (constructor ) : false == take strategy 2 ( pointer to function) - * @return TODO - * @throws BacktrackException request a backtrack - */ + * Serves as the catch-all for all complicated declarations, including + * function-definitions. + * + * simpleDeclaration : (declSpecifier)* (initDeclarator ("," + * initDeclarator)*)? (";" | { functionBody } + * + * Notes: - append functionDefinition stuff to end of this rule + * + * To do: - work in functionTryBlock + * + * @param container + * IParserCallback object which serves as the owner scope for + * this declaration. + * @param tryConstructor + * true == take strategy1 (constructor ) : false == take strategy + * 2 ( pointer to function) + * @return TODO + * @throws BacktrackException + * request a backtrack + */ protected IASTDeclaration simpleDeclaration( SimpleDeclarationStrategy strategy, IASTScope scope, @@ -1041,7 +1074,8 @@ public abstract class Parser extends ExpressionParser implements IParser throws BacktrackException, EndOfFileException { IToken firstToken = LA(1); - if( firstToken.getType() == IToken.tLBRACE ) throw backtrack; + int firstOffset = firstToken.getOffset(); + if( firstToken.getType() == IToken.tLBRACE ) throwBacktrack(firstToken.getOffset()); DeclarationWrapper sdw = new DeclarationWrapper(scope, firstToken.getOffset(), firstToken.getLineNumber(), ownerTemplate); firstToken = null; // necessary for scalability @@ -1072,7 +1106,7 @@ public abstract class Parser extends ExpressionParser implements IParser catch (Exception e1) { logException( "simpleDeclaration:createSimpleTypeSpecifier", e1 ); //$NON-NLS-1$ - throw backtrack; + throwBacktrack(firstOffset); } try { @@ -1113,10 +1147,10 @@ public abstract class Parser extends ExpressionParser implements IParser break; case IToken.tRPAREN: if( ! fromCatchHandler ) - throw backtrack; + throwBacktrack(firstOffset); break; default: - throw backtrack; + throwBacktrack(firstOffset); } if( ! consumedSemi ) @@ -1128,7 +1162,7 @@ public abstract class Parser extends ExpressionParser implements IParser } if( hasFunctionTryBlock && ! hasFunctionBody ) - throw backtrack; + throwBacktrack(firstOffset); } List l = null; @@ -1138,17 +1172,17 @@ public abstract class Parser extends ExpressionParser implements IParser } catch (ASTSemanticException e) { - throw backtrack; + throwBacktrack(e.getProblem()); } catch( Exception e ) { logException( "simpleDecl", e ); //$NON-NLS-1$ - throw backtrack; + throwBacktrack(firstOffset); } if (hasFunctionBody && l.size() != 1) { - throw backtrack; //TODO Should be an IProblem + throwBacktrack(firstOffset); //TODO Should be an IProblem } if (!l.isEmpty()) // no need to do this unless we have a declarator { @@ -1174,7 +1208,7 @@ public abstract class Parser extends ExpressionParser implements IParser ((IASTSimpleTypeSpecifier)sdw.getTypeSpecifier()).releaseReferences( astFactory.getReferenceManager() ); if ( !( declaration instanceof IASTScope ) ) - throw backtrack; + throwBacktrack(firstOffset); handleFunctionBody((IASTScope)declaration ); ((IASTOffsetableElement)declaration).setEndingOffsetAndLineNumber( @@ -1207,7 +1241,7 @@ public abstract class Parser extends ExpressionParser implements IParser catch (Exception e1) { logException( "simpleDeclaration:createTypeSpecDeclaration", e1 ); //$NON-NLS-1$ - throw backtrack; + throwBacktrack(firstOffset); } return null; @@ -1215,7 +1249,8 @@ public abstract class Parser extends ExpressionParser implements IParser { if( simpleTypeSpecifier != null ) simpleTypeSpecifier.releaseReferences(astFactory.getReferenceManager()); - throw be; + throwBacktrack(be); + return null; } catch( EndOfFileException eof ) { @@ -1248,71 +1283,67 @@ public abstract class Parser extends ExpressionParser implements IParser } } /** - * This method parses a constructor chain - * ctorinitializer: : meminitializerlist - * meminitializerlist: meminitializer | meminitializer , meminitializerlist - * meminitializer: meminitializerid | ( expressionlist? ) - * meminitializerid: ::? nestednamespecifier? - * classname - * identifier - * @param declarator IParserCallback object that represents the declarator (constructor) that owns this initializer - * @throws BacktrackException request a backtrack - */ + * This method parses a constructor chain ctorinitializer: : + * meminitializerlist meminitializerlist: meminitializer | meminitializer , + * meminitializerlist meminitializer: meminitializerid | ( expressionlist? ) + * meminitializerid: ::? nestednamespecifier? classname identifier + * + * @param declarator + * IParserCallback object that represents the declarator + * (constructor) that owns this initializer + * @throws BacktrackException + * request a backtrack + */ protected void ctorInitializer(Declarator d ) throws EndOfFileException, BacktrackException { - consume(IToken.tCOLON); + int startingOffset = consume(IToken.tCOLON).getOffset(); IASTScope scope = d.getDeclarationWrapper().getScope(); - try + for (;;) { - for (;;) + if (LT(1) == IToken.tLBRACE) + break; + + + ITokenDuple duple = name(scope, CompletionKind.SINGLE_NAME_REFERENCE, KeywordSetKey.EMPTY ); + + consume(IToken.tLPAREN); + IASTExpression expressionList = null; + + expressionList = expression(d.getDeclarationWrapper().getScope(), CompletionKind.SINGLE_NAME_REFERENCE, KeywordSetKey.EXPRESSION); + + consume(IToken.tRPAREN); + + try { - if (LT(1) == IToken.tLBRACE) - break; - - - ITokenDuple duple = name(scope, CompletionKind.SINGLE_NAME_REFERENCE, KeywordSetKey.EMPTY ); - - consume(IToken.tLPAREN); - IASTExpression expressionList = null; - - expressionList = expression(d.getDeclarationWrapper().getScope(), CompletionKind.SINGLE_NAME_REFERENCE, KeywordSetKey.EXPRESSION); - - consume(IToken.tRPAREN); - - try - { - d.addConstructorMemberInitializer( - astFactory.createConstructorMemberInitializer( - d.getDeclarationWrapper().getScope(), - duple, expressionList)); - } - catch (Exception e1) - { - logException( "ctorInitializer:addConstructorMemberInitializer", e1 ); //$NON-NLS-1$ - throw backtrack; - } - if (LT(1) == IToken.tLBRACE) - break; - consume(IToken.tCOMMA); + d.addConstructorMemberInitializer( + astFactory.createConstructorMemberInitializer( + d.getDeclarationWrapper().getScope(), + duple, expressionList)); } + catch (Exception e1) + { + logException( "ctorInitializer:addConstructorMemberInitializer", e1 ); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + if (LT(1) == IToken.tLBRACE) + break; + consume(IToken.tCOMMA); } - catch (BacktrackException bt) - { - - throw backtrack; - } - + } protected boolean constructInitializersInParameters = true; protected boolean constructInitializersInDeclarations = true; /** - * This routine parses a parameter declaration - * - * @param containerObject The IParserCallback object representing the parameterDeclarationClause owning the parm. - * @throws BacktrackException request a backtrack - */ + * This routine parses a parameter declaration + * + * @param containerObject + * The IParserCallback object representing the + * parameterDeclarationClause owning the parm. + * @throws BacktrackException + * request a backtrack + */ protected void parameterDeclaration( IParameterCollection collection, IASTScope scope) throws BacktrackException, EndOfFileException @@ -1343,12 +1374,12 @@ public abstract class Parser extends ExpressionParser implements IParser } catch (ASTSemanticException e) { - throw backtrack; + throwBacktrack(e.getProblem()); } catch (Exception e) { logException( "parameterDeclaration:createSimpleTypeSpecifier", e ); //$NON-NLS-1$ - throw backtrack; + throwBacktrack(current.getOffset()); } setCompletionValues(scope,CompletionKind.SINGLE_NAME_REFERENCE,KeywordSetKey.EMPTY ); @@ -1359,12 +1390,13 @@ public abstract class Parser extends ExpressionParser implements IParser sdw.setEndingOffsetAndLineNumber( lastToken.getEndOffset(), lastToken.getLineNumber() ); if (current == LA(1)) - throw backtrack; + throwBacktrack(current.getOffset()); collection.addParameter(sdw); } /** - * This class represents the state and strategy for parsing declarationSpecifierSequences - */ + * This class represents the state and strategy for parsing + * declarationSpecifierSequences + */ public class Flags { private boolean encounteredTypename = false; @@ -1381,1440 +1413,1371 @@ public abstract class Parser extends ExpressionParser implements IParser constructor = c; } /** - * @return true if we have encountered a simple type up to this point, false otherwise - */ + * @return true if we have encountered a simple type up to this point, + * false otherwise + */ public boolean haveEncounteredRawType() { return encounteredRawType; } /** - * @return true if we have encountered a typename up to this point, false otherwise - */ + * @return true if we have encountered a typename up to this point, + * false otherwise + */ public boolean haveEncounteredTypename() { return encounteredTypename; } /** - * @param b - set to true if we encounter a raw type (int, short, etc.) - */ + * @param b - + * set to true if we encounter a raw type (int, short, etc.) + */ public void setEncounteredRawType(boolean b) { encounteredRawType = b; } /** - * @param b - set to true if we encounter a typename - */ + * @param b - + * set to true if we encounter a typename + */ public void setEncounteredTypename(boolean b) { encounteredTypename = b; } /** - * @return true if we are parsing for a ParameterDeclaration - */ + * @return true if we are parsing for a ParameterDeclaration + */ public boolean isForParameterDeclaration() { return parm; } /** - * @return whether or not we are attempting the constructor strategy or not - */ + * @return whether or not we are attempting the constructor strategy or + * not + */ public boolean isForConstructor() { return constructor; } } /** - * @param flags input flags that are used to make our decision - * @return whether or not this looks like a constructor (true or false) - * @throws EndOfFileException we could encounter EOF while looking ahead - */ - private boolean lookAheadForConstructorOrConversion(Flags flags, DeclarationWrapper sdw, CompletionKind kind ) - throws EndOfFileException - { - if (flags.isForParameterDeclaration()) - return false; - if (queryLookaheadCapability(2) && LT(2) == IToken.tLPAREN && flags.isForConstructor()) - return true; - - IToken mark = mark(); - Declarator d = new Declarator( sdw ); - try - { - try - { - consumeTemplatedOperatorName( d, kind ); - } - catch (BacktrackException e) - { - backup( mark ); - return false; - } - catch ( EndOfFileException eof ) - { - backup( mark ); - return false; + * @param flags + * input flags that are used to make our decision + * @return whether or not this looks like a constructor (true or false) + * @throws EndOfFileException + * we could encounter EOF while looking ahead + */ + private boolean lookAheadForConstructorOrConversion(Flags flags, + DeclarationWrapper sdw, CompletionKind kind) + throws EndOfFileException { + if (flags.isForParameterDeclaration()) + return false; + if (queryLookaheadCapability(2) && LT(2) == IToken.tLPAREN + && flags.isForConstructor()) + return true; + + IToken mark = mark(); + Declarator d = new Declarator(sdw); + try { + try { + consumeTemplatedOperatorName(d, kind); + } catch (BacktrackException e) { + backup(mark); + return false; + } catch (EndOfFileException eof) { + backup(mark); + return false; + } + + ITokenDuple duple = d.getNameDuple(); + if (duple == null) { + backup(mark); + return false; + } + + int lastColon = duple.findLastTokenType(IToken.tCOLON); + if (lastColon == -1) { + int lt1 = LT(1); + backup(mark); + return flags.isForConstructor() && (lt1 == IToken.tLPAREN); + } + + IToken className = null; + int index = lastColon - 1; + if (duple.getToken(index).getType() == IToken.tGT) { + int depth = -1; + while (depth == -1) { + if (duple.getToken(--index).getType() == IToken.tLT) + ++depth; + } + className = duple.getToken(index); + } + + boolean result = className.getImage().equals(duple.getLastToken()); + backup(mark); + return result; + } finally { + if (d.getNameDuple() != null + && d.getNameDuple().getTemplateIdArgLists() != null) { + List[] arrayOfLists = d.getNameDuple().getTemplateIdArgLists(); + for (int i = 0; i < arrayOfLists.length; ++i) { + if (arrayOfLists[i] == null) + continue; + for (int j = 0; j < arrayOfLists[i].size(); ++j) { + IASTExpression e = (IASTExpression) arrayOfLists[i] + .get(j); + e.freeReferences(astFactory.getReferenceManager()); + + } + } } - - ITokenDuple duple = d.getNameDuple(); - if( duple == null ) - { - backup( mark ); - return false; - } - - int lastColon = duple.findLastTokenType(IToken.tCOLON); - if( lastColon == -1 ) - { - int lt1 = LT(1); - backup( mark ); - return flags.isForConstructor() && (lt1 == IToken.tLPAREN); - } - - IToken className = null; - int index = lastColon - 1; - if( duple.getToken( index ).getType() == IToken.tGT ) - { - int depth = -1; - while( depth == -1 ) - { - if( duple.getToken( --index ).getType() == IToken.tLT ) - ++depth; - } - className = duple.getToken( index ); - } - - boolean result = className.getImage().equals( duple.getLastToken()); - backup( mark ); - return result; } - finally - { - if( d.getNameDuple() != null && d.getNameDuple().getTemplateIdArgLists() != null ) - { - List [] arrayOfLists = d.getNameDuple().getTemplateIdArgLists(); - for( int i = 0; i < arrayOfLists.length; ++i ) - { - if( arrayOfLists[i] == null ) continue; - for( int j = 0; j < arrayOfLists[i].size(); ++j ) - { - IASTExpression e = (IASTExpression) arrayOfLists[i].get(j); - e.freeReferences( astFactory.getReferenceManager()); - - } - } - } - } - } - /** - * @param flags input flags that are used to make our decision - * @return whether or not this looks like a a declarator follows - * @throws EndOfFileException we could encounter EOF while looking ahead - */ - private boolean lookAheadForDeclarator(Flags flags) throws EndOfFileException - { - return flags.haveEncounteredTypename() - && ( (LT(2) != IToken.tIDENTIFIER - || (LT(3) != IToken.tLPAREN && LT(3) != IToken.tASSIGN)) - && !LA(2).isPointer()); - } - /** - * This function parses a declaration specifier sequence, as according to the ANSI C++ spec. - * - * declSpecifier - * : "auto" | "register" | "static" | "extern" | "mutable" - * | "inline" | "virtual" | "explicit" - * | "char" | "wchar_t" | "bool" | "short" | "int" | "long" - * | "signed" | "unsigned" | "float" | "double" | "void" - * | "const" | "volatile" - * | "friend" | "typedef" - * | ("typename")? name - * | {"class"|"struct"|"union"} classSpecifier - * | {"enum"} enumSpecifier - * - * Notes: - * - folded in storageClassSpecifier, typeSpecifier, functionSpecifier - * - folded elaboratedTypeSpecifier into classSpecifier and enumSpecifier - * - find template names in name - * - * @param decl IParserCallback object representing the declaration that owns this specifier sequence - * @param parm Is this for a parameter declaration (true) or simple declaration (false) - * @param tryConstructor true for constructor, false for pointer to function strategy - * @throws BacktrackException request a backtrack - */ - protected void declSpecifierSeq( - DeclarationWrapper sdw, - boolean parm, - boolean tryConstructor, CompletionKind kind, KeywordSetKey key ) - throws BacktrackException, EndOfFileException - { - Flags flags = new Flags(parm, tryConstructor); - IToken typeNameBegin = null; - IToken typeNameEnd = null; - declSpecifiers : for (;;) - { - switch (LT(1)) - { - case IToken.t_inline : - consume(); - sdw.setInline(true); - break; - case IToken.t_auto : - consume(); - sdw.setAuto(true); - break; - case IToken.t_register : - sdw.setRegister(true); - consume(); - break; - case IToken.t_static : - sdw.setStatic(true); - consume(); - break; - case IToken.t_extern : - sdw.setExtern(true); - consume(); - break; - case IToken.t_mutable : - sdw.setMutable(true); - consume(); - break; - case IToken.t_virtual : - sdw.setVirtual(true); - consume(); - break; - case IToken.t_explicit : - sdw.setExplicit(true); - consume(); - break; - case IToken.t_typedef : - sdw.setTypedef(true); - consume(); - break; - case IToken.t_friend : - sdw.setFriend(true); - consume(); - break; - case IToken.t_const : - sdw.setConst(true); - consume(); - break; - case IToken.t_volatile : - sdw.setVolatile(true); - consume(); - break; - case IToken.t_signed : - sdw.setSigned(true); - if (typeNameBegin == null) - typeNameBegin = LA(1); - typeNameEnd = LA(1); - flags.setEncounteredRawType(true); + } + /** + * @param flags + * input flags that are used to make our decision + * @return whether or not this looks like a a declarator follows + * @throws EndOfFileException + * we could encounter EOF while looking ahead + */ + private boolean lookAheadForDeclarator(Flags flags) + throws EndOfFileException { + return flags.haveEncounteredTypename() + && ((LT(2) != IToken.tIDENTIFIER || (LT(3) != IToken.tLPAREN && LT(3) != IToken.tASSIGN)) && !LA( + 2).isPointer()); + } + /** + * This function parses a declaration specifier sequence, as according to + * the ANSI C++ spec. + * + * declSpecifier : "auto" | "register" | "static" | "extern" | "mutable" | + * "inline" | "virtual" | "explicit" | "char" | "wchar_t" | "bool" | "short" | + * "int" | "long" | "signed" | "unsigned" | "float" | "double" | "void" | + * "const" | "volatile" | "friend" | "typedef" | ("typename")? name | + * {"class"|"struct"|"union"} classSpecifier | {"enum"} enumSpecifier + * + * Notes: - folded in storageClassSpecifier, typeSpecifier, + * functionSpecifier - folded elaboratedTypeSpecifier into classSpecifier + * and enumSpecifier - find template names in name + * + * @param decl + * IParserCallback object representing the declaration that owns + * this specifier sequence + * @param parm + * Is this for a parameter declaration (true) or simple + * declaration (false) + * @param tryConstructor + * true for constructor, false for pointer to function strategy + * @throws BacktrackException + * request a backtrack + */ + protected void declSpecifierSeq(DeclarationWrapper sdw, boolean parm, + boolean tryConstructor, CompletionKind kind, KeywordSetKey key) + throws BacktrackException, EndOfFileException { + Flags flags = new Flags(parm, tryConstructor); + IToken typeNameBegin = null; + IToken typeNameEnd = null; + declSpecifiers : for (;;) { + switch (LT(1)) { + case IToken.t_inline : consume(); - sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.INT); - break; - case IToken.t_unsigned : - sdw.setUnsigned(true); - if (typeNameBegin == null) - typeNameBegin = LA(1); - typeNameEnd = LA(1); - flags.setEncounteredRawType(true); + sdw.setInline(true); + break; + case IToken.t_auto : consume(); - sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.INT); - break; - case IToken.t_short : - sdw.setShort(true); - if (typeNameBegin == null) - typeNameBegin = LA(1); - typeNameEnd = LA(1); - flags.setEncounteredRawType(true); + sdw.setAuto(true); + break; + case IToken.t_register : + sdw.setRegister(true); consume(); - sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.INT); - break; - case IToken.t_long : - if (typeNameBegin == null) - typeNameBegin = LA(1); - typeNameEnd = LA(1); - flags.setEncounteredRawType(true); + break; + case IToken.t_static : + sdw.setStatic(true); consume(); - sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.INT); - sdw.setLong(true); - break; - case IToken.t__Complex : - consume( IToken.t__Complex ); + break; + case IToken.t_extern : + sdw.setExtern(true); + consume(); + break; + case IToken.t_mutable : + sdw.setMutable(true); + consume(); + break; + case IToken.t_virtual : + sdw.setVirtual(true); + consume(); + break; + case IToken.t_explicit : + sdw.setExplicit(true); + consume(); + break; + case IToken.t_typedef : + sdw.setTypedef(true); + consume(); + break; + case IToken.t_friend : + sdw.setFriend(true); + consume(); + break; + case IToken.t_const : + sdw.setConst(true); + consume(); + break; + case IToken.t_volatile : + sdw.setVolatile(true); + consume(); + break; + case IToken.t_signed : + sdw.setSigned(true); if (typeNameBegin == null) typeNameBegin = LA(1); typeNameEnd = LA(1); - sdw.setComplex( true ); + flags.setEncounteredRawType(true); + consume(); + sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.INT); + break; + case IToken.t_unsigned : + sdw.setUnsigned(true); + if (typeNameBegin == null) + typeNameBegin = LA(1); + typeNameEnd = LA(1); + flags.setEncounteredRawType(true); + consume(); + sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.INT); + break; + case IToken.t_short : + sdw.setShort(true); + if (typeNameBegin == null) + typeNameBegin = LA(1); + typeNameEnd = LA(1); + flags.setEncounteredRawType(true); + consume(); + sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.INT); + break; + case IToken.t_long : + if (typeNameBegin == null) + typeNameBegin = LA(1); + typeNameEnd = LA(1); + flags.setEncounteredRawType(true); + consume(); + sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.INT); + sdw.setLong(true); + break; + case IToken.t__Complex : + consume(IToken.t__Complex); + if (typeNameBegin == null) + typeNameBegin = LA(1); + typeNameEnd = LA(1); + sdw.setComplex(true); break; case IToken.t__Imaginary : - consume( IToken.t__Imaginary ); + consume(IToken.t__Imaginary); if (typeNameBegin == null) typeNameBegin = LA(1); typeNameEnd = LA(1); - sdw.setImaginary( true ); - break; - case IToken.t_char : - if (typeNameBegin == null) - typeNameBegin = LA(1); - typeNameEnd = LA(1); - flags.setEncounteredRawType(true); + sdw.setImaginary(true); + break; + case IToken.t_char : + if (typeNameBegin == null) + typeNameBegin = LA(1); + typeNameEnd = LA(1); + flags.setEncounteredRawType(true); consume(); - sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.CHAR); - break; - case IToken.t_wchar_t : - if (typeNameBegin == null) - typeNameBegin = LA(1); - typeNameEnd = LA(1); - flags.setEncounteredRawType(true); + sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.CHAR); + break; + case IToken.t_wchar_t : + if (typeNameBegin == null) + typeNameBegin = LA(1); + typeNameEnd = LA(1); + flags.setEncounteredRawType(true); consume(); - sdw.setSimpleType( - IASTSimpleTypeSpecifier.Type.WCHAR_T); - break; - case IToken.t_bool : - if (typeNameBegin == null) - typeNameBegin = LA(1); - typeNameEnd = LA(1); - flags.setEncounteredRawType(true); + sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.WCHAR_T); + break; + case IToken.t_bool : + if (typeNameBegin == null) + typeNameBegin = LA(1); + typeNameEnd = LA(1); + flags.setEncounteredRawType(true); consume(); - sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.BOOL); - break; - case IToken.t__Bool: + sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.BOOL); + break; + case IToken.t__Bool : if (typeNameBegin == null) typeNameBegin = LA(1); typeNameEnd = LA(1); flags.setEncounteredRawType(true); consume(); sdw.setSimpleType(IASTSimpleTypeSpecifier.Type._BOOL); - break; - case IToken.t_int : - if (typeNameBegin == null) - typeNameBegin = LA(1); - typeNameEnd = LA(1); - flags.setEncounteredRawType(true); + break; + case IToken.t_int : + if (typeNameBegin == null) + typeNameBegin = LA(1); + typeNameEnd = LA(1); + flags.setEncounteredRawType(true); consume(); - sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.INT); - break; - case IToken.t_float : - if (typeNameBegin == null) - typeNameBegin = LA(1); - typeNameEnd = LA(1); - flags.setEncounteredRawType(true); + sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.INT); + break; + case IToken.t_float : + if (typeNameBegin == null) + typeNameBegin = LA(1); + typeNameEnd = LA(1); + flags.setEncounteredRawType(true); consume(); - sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.FLOAT); - break; - case IToken.t_double : - if (typeNameBegin == null) - typeNameBegin = LA(1); - typeNameEnd = LA(1); - flags.setEncounteredRawType(true); + sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.FLOAT); + break; + case IToken.t_double : + if (typeNameBegin == null) + typeNameBegin = LA(1); + typeNameEnd = LA(1); + flags.setEncounteredRawType(true); consume(); - sdw.setSimpleType( - IASTSimpleTypeSpecifier.Type.DOUBLE); - break; - case IToken.t_void : - if (typeNameBegin == null) - typeNameBegin = LA(1); - typeNameEnd = LA(1); - flags.setEncounteredRawType(true); + sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.DOUBLE); + break; + case IToken.t_void : + if (typeNameBegin == null) + typeNameBegin = LA(1); + typeNameEnd = LA(1); + flags.setEncounteredRawType(true); consume(); - sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.VOID); - break; - case IToken.t_typename : - sdw.setTypenamed(true); - consume(IToken.t_typename ); - IToken first = LA(1); - IToken last = null; - last = name(sdw.getScope(), CompletionKind.TYPE_REFERENCE, KeywordSetKey.EMPTY).getLastToken(); - if (LT(1) == IToken.t_template) - { - consume(IToken.t_template); - last = templateId(sdw.getScope(), CompletionKind.SINGLE_NAME_REFERENCE ); - } - if( sdw.getName() != null ) - first = sdw.getName().getFirstToken(); - ITokenDuple duple = TokenFactory.createTokenDuple(first, last); - sdw.setTypeName(duple); + sdw.setSimpleType(IASTSimpleTypeSpecifier.Type.VOID); + break; + case IToken.t_typename : + sdw.setTypenamed(true); + consume(IToken.t_typename); + IToken first = LA(1); + IToken last = null; + last = name(sdw.getScope(), CompletionKind.TYPE_REFERENCE, + KeywordSetKey.EMPTY).getLastToken(); + if (LT(1) == IToken.t_template) { + consume(IToken.t_template); + last = templateId(sdw.getScope(), + CompletionKind.SINGLE_NAME_REFERENCE); + } + if (sdw.getName() != null) + first = sdw.getName().getFirstToken(); + ITokenDuple duple = TokenFactory.createTokenDuple(first, + last); + sdw.setTypeName(duple); flags.setEncounteredTypename(true); - break; - case IToken.tCOLONCOLON : - sdw.setGloballyQualified( true ); - consume( IToken.tCOLONCOLON ); - break; - case IToken.tIDENTIFIER : - // TODO - Kludgy way to handle constructors/destructors - if (flags.haveEncounteredRawType()) - { - setTypeName(sdw, typeNameBegin, typeNameEnd); - return; - } - if (parm && flags.haveEncounteredTypename()) - { - setTypeName(sdw, typeNameBegin, typeNameEnd); - return; - } - if (lookAheadForConstructorOrConversion(flags, sdw, kind)) - { - setTypeName(sdw, typeNameBegin, typeNameEnd); - return; - } - if (lookAheadForDeclarator(flags)) - { - setTypeName(sdw, typeNameBegin, typeNameEnd); - return; - } - setCompletionValues(sdw.getScope(), kind, key ); - ITokenDuple d = name(sdw.getScope(), kind, key ); - sdw.setTypeName(d); - sdw.setSimpleType( IASTSimpleTypeSpecifier.Type.CLASS_OR_TYPENAME ); - flags.setEncounteredTypename(true); - break; - case IToken.t_class : - case IToken.t_struct : - case IToken.t_union : - try - { - classSpecifier(sdw); + break; + case IToken.tCOLONCOLON : + sdw.setGloballyQualified(true); + consume(IToken.tCOLONCOLON); + break; + case IToken.tIDENTIFIER : + // TODO - Kludgy way to handle constructors/destructors + if (flags.haveEncounteredRawType()) { + setTypeName(sdw, typeNameBegin, typeNameEnd); + return; + } + if (parm && flags.haveEncounteredTypename()) { + setTypeName(sdw, typeNameBegin, typeNameEnd); + return; + } + if (lookAheadForConstructorOrConversion(flags, sdw, kind)) { + setTypeName(sdw, typeNameBegin, typeNameEnd); + return; + } + if (lookAheadForDeclarator(flags)) { + setTypeName(sdw, typeNameBegin, typeNameEnd); + return; + } + setCompletionValues(sdw.getScope(), kind, key); + ITokenDuple d = name(sdw.getScope(), kind, key); + sdw.setTypeName(d); + sdw + .setSimpleType(IASTSimpleTypeSpecifier.Type.CLASS_OR_TYPENAME); + flags.setEncounteredTypename(true); + break; + case IToken.t_class : + case IToken.t_struct : + case IToken.t_union : + try { + classSpecifier(sdw); flags.setEncounteredTypename(true); - break; - } - catch (BacktrackException bt) - { - elaboratedTypeSpecifier(sdw); - flags.setEncounteredTypename(true); - break; - } - case IToken.t_enum : - try - { - enumSpecifier(sdw); - flags.setEncounteredTypename(true); - break; - } - catch (BacktrackException bt) - { - // this is an elaborated class specifier - elaboratedTypeSpecifier(sdw); - flags.setEncounteredTypename(true); - break; - } - default : - if( extension.canHandleDeclSpecifierSequence( LT(1))) - { - IParserExtension.IDeclSpecifierExtensionResult declSpecExtResult = extension.parseDeclSpecifierSequence( this, flags, sdw, kind, key ); - if( declSpecExtResult != null ) - { - flags = declSpecExtResult.getFlags(); - if( typeNameBegin == null ) - typeNameBegin = declSpecExtResult.getFirstToken(); - typeNameEnd = declSpecExtResult.getLastToken(); - break; - } - break declSpecifiers; - } - break declSpecifiers; - } - } - setTypeName(sdw, typeNameBegin, typeNameEnd); - return; - } - - + break; + } catch (BacktrackException bt) { + elaboratedTypeSpecifier(sdw); + flags.setEncounteredTypename(true); + break; + } + case IToken.t_enum : + try { + enumSpecifier(sdw); + flags.setEncounteredTypename(true); + break; + } catch (BacktrackException bt) { + // this is an elaborated class specifier + elaboratedTypeSpecifier(sdw); + flags.setEncounteredTypename(true); + break; + } + default : + if (extension.canHandleDeclSpecifierSequence(LT(1))) { + IParserExtension.IDeclSpecifierExtensionResult declSpecExtResult = extension + .parseDeclSpecifierSequence(this, flags, sdw, + kind, key); + if (declSpecExtResult != null) { + flags = declSpecExtResult.getFlags(); + if (typeNameBegin == null) + typeNameBegin = declSpecExtResult + .getFirstToken(); + typeNameEnd = declSpecExtResult.getLastToken(); + break; + } + break declSpecifiers; + } + break declSpecifiers; + } + } + setTypeName(sdw, typeNameBegin, typeNameEnd); + return; + } /** * @param sdw * @param typeNameBegin * @param typeNameEnd */ - private void setTypeName(DeclarationWrapper sdw, IToken typeNameBegin, IToken typeNameEnd) { + private void setTypeName(DeclarationWrapper sdw, IToken typeNameBegin, + IToken typeNameEnd) { if (typeNameBegin != null) - sdw.setTypeName( - TokenFactory.createTokenDuple(typeNameBegin, typeNameEnd)); + sdw.setTypeName(TokenFactory.createTokenDuple(typeNameBegin, + typeNameEnd)); } + /** + * Parse an elaborated type specifier. + * + * @param decl + * Declaration which owns the elaborated type + * @throws BacktrackException + * request a backtrack + */ + protected void elaboratedTypeSpecifier(DeclarationWrapper sdw) + throws BacktrackException, EndOfFileException { + // this is an elaborated class specifier + IToken t = consume(); + ASTClassKind eck = null; + CompletionKind completionKind = null; + + switch (t.getType()) { + case IToken.t_class : + eck = ASTClassKind.CLASS; + completionKind = CompletionKind.CLASS_REFERENCE; + break; + case IToken.t_struct : + eck = ASTClassKind.STRUCT; + completionKind = CompletionKind.STRUCT_REFERENCE; + break; + case IToken.t_union : + eck = ASTClassKind.UNION; + completionKind = CompletionKind.UNION_REFERENCE; + break; + case IToken.t_enum : + eck = ASTClassKind.ENUM; + completionKind = CompletionKind.ENUM_REFERENCE; + break; + default : + backup(t); + throwBacktrack(t.getOffset()); + } + + ITokenDuple d = name(sdw.getScope(), completionKind, + KeywordSetKey.EMPTY); + IASTTypeSpecifier elaboratedTypeSpec = null; + final boolean isForewardDecl = (LT(1) == IToken.tSEMI); + + try { + elaboratedTypeSpec = astFactory.createElaboratedTypeSpecifier(sdw + .getScope(), eck, d, t.getOffset(), t.getLineNumber(), d + .getLastToken().getEndOffset(), d.getLastToken() + .getLineNumber(), isForewardDecl, sdw.isFriend()); + } catch (ASTSemanticException e) { + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException( + "elaboratedTypeSpecifier:createElaboratedTypeSpecifier", e); //$NON-NLS-1$ + throwBacktrack(t.getOffset()); + } + sdw.setTypeSpecifier(elaboratedTypeSpec); + + if (isForewardDecl) + ((IASTElaboratedTypeSpecifier) elaboratedTypeSpec).acceptElement( + requestor, astFactory.getReferenceManager()); + } + /** + * Parses the initDeclarator construct of the ANSI C++ spec. + * + * initDeclarator : declarator ("=" initializerClause | "(" expressionList + * ")")? + * + * @param constructInitializers + * TODO + * @param owner + * IParserCallback object that represents the owner declaration + * object. + * @return declarator that this parsing produced. + * @throws BacktrackException + * request a backtrack + */ + protected Declarator initDeclarator(DeclarationWrapper sdw, + SimpleDeclarationStrategy strategy, CompletionKind kind, + boolean constructInitializers) throws EndOfFileException, + BacktrackException { + Declarator d = declarator(sdw, sdw.getScope(), strategy, kind); + + try { + astFactory.constructExpressions(constructInitializers); + if (language == ParserLanguage.CPP) + optionalCPPInitializer(d, constructInitializers); + else if (language == ParserLanguage.C) + optionalCInitializer(d, constructInitializers); + sdw.addDeclarator(d); + return d; + } finally { + astFactory.constructExpressions(true); + } + } + + protected void optionalCPPInitializer(Declarator d, + boolean constructInitializers) throws EndOfFileException, + BacktrackException { + // handle initializer + final IASTScope scope = d.getDeclarationWrapper().getScope(); + setCompletionValues(scope, CompletionKind.NO_SUCH_KIND, + KeywordSetKey.EMPTY); + if (LT(1) == IToken.tASSIGN) { + consume(IToken.tASSIGN); + setCompletionValues(scope, CompletionKind.SINGLE_NAME_REFERENCE, + KeywordSetKey.EMPTY); + throwAwayMarksForInitializerClause(d); + try + { + IASTInitializerClause clause = initializerClause(scope, + constructInitializers); + d.setInitializerClause(clause); + } + catch( EndOfFileException eof ) + { + failParse(); + throw eof; + } + setCompletionValues(scope, CompletionKind.NO_SUCH_KIND, + KeywordSetKey.EMPTY); + } else if (LT(1) == IToken.tLPAREN) { + // initializer in constructor + consume(IToken.tLPAREN); // EAT IT! + setCompletionValues(scope, CompletionKind.SINGLE_NAME_REFERENCE, + KeywordSetKey.EMPTY); + IASTExpression astExpression = null; + astExpression = expression(scope, + CompletionKind.SINGLE_NAME_REFERENCE, + KeywordSetKey.EXPRESSION); + setCompletionValues(scope, CompletionKind.NO_SUCH_KIND, + KeywordSetKey.EMPTY); + consume(IToken.tRPAREN); + d.setConstructorExpression(astExpression); + } + } /** - * Parse an elaborated type specifier. - * - * @param decl Declaration which owns the elaborated type - * @throws BacktrackException request a backtrack - */ - protected void elaboratedTypeSpecifier(DeclarationWrapper sdw) - throws BacktrackException, EndOfFileException - { - // this is an elaborated class specifier - IToken t = consume(); - ASTClassKind eck = null; - CompletionKind completionKind = null; - - switch (t.getType()) - { - case IToken.t_class : - eck = ASTClassKind.CLASS; - completionKind = CompletionKind.CLASS_REFERENCE; - break; - case IToken.t_struct : - eck = ASTClassKind.STRUCT; - completionKind = CompletionKind.STRUCT_REFERENCE; - break; - case IToken.t_union : - eck = ASTClassKind.UNION; - completionKind = CompletionKind.UNION_REFERENCE; - break; - case IToken.t_enum : - eck = ASTClassKind.ENUM; - completionKind = CompletionKind.ENUM_REFERENCE; - break; - default : - backup( t ); - throw backtrack; - } - - ITokenDuple d = name(sdw.getScope(), completionKind, KeywordSetKey.EMPTY); - IASTTypeSpecifier elaboratedTypeSpec = null; - final boolean isForewardDecl = ( LT(1) == IToken.tSEMI ); - - try - { - elaboratedTypeSpec = - astFactory.createElaboratedTypeSpecifier( - sdw.getScope(), - eck, - d, - t.getOffset(), - t.getLineNumber(), - d.getLastToken().getEndOffset(), d.getLastToken().getLineNumber(), isForewardDecl, sdw.isFriend() ); - } - catch (ASTSemanticException e) - { - failParse(); - throw backtrack; - } catch (Exception e) - { - logException( "elaboratedTypeSpecifier:createElaboratedTypeSpecifier", e ); //$NON-NLS-1$ - throw backtrack; - } - sdw.setTypeSpecifier(elaboratedTypeSpec); - - if( isForewardDecl ) - ((IASTElaboratedTypeSpecifier)elaboratedTypeSpec).acceptElement( requestor, astFactory.getReferenceManager() ); - } - /** - * Parses the initDeclarator construct of the ANSI C++ spec. - * - * initDeclarator - * : declarator ("=" initializerClause | "(" expressionList ")")? - * @param constructInitializers TODO - * @param owner IParserCallback object that represents the owner declaration object. - * @return declarator that this parsing produced. - * @throws BacktrackException request a backtrack - */ - protected Declarator initDeclarator( - DeclarationWrapper sdw, SimpleDeclarationStrategy strategy, CompletionKind kind, boolean constructInitializers ) - throws EndOfFileException, BacktrackException - { - Declarator d = declarator(sdw, sdw.getScope(), strategy, kind ); - - try - { - astFactory.constructExpressions(constructInitializers); - if( language == ParserLanguage.CPP ) - optionalCPPInitializer(d, constructInitializers); - else if( language == ParserLanguage.C ) - optionalCInitializer(d, constructInitializers); - sdw.addDeclarator(d); - return d; - } - finally - { - astFactory.constructExpressions( true ); - } - } - - protected void optionalCPPInitializer(Declarator d, boolean constructInitializers) - throws EndOfFileException, BacktrackException - { - // handle initializer - final IASTScope scope = d.getDeclarationWrapper().getScope(); - setCompletionValues(scope,CompletionKind.NO_SUCH_KIND,KeywordSetKey.EMPTY); - if (LT(1) == IToken.tASSIGN) - { - consume(IToken.tASSIGN); - setCompletionValues(scope,CompletionKind.SINGLE_NAME_REFERENCE,KeywordSetKey.EMPTY); - throwAwayMarksForInitializerClause(d); - IASTInitializerClause clause = initializerClause(scope,constructInitializers); - d.setInitializerClause(clause); - setCompletionValues(scope,CompletionKind.NO_SUCH_KIND,KeywordSetKey.EMPTY); - } - else if (LT(1) == IToken.tLPAREN ) - { - // initializer in constructor - consume(IToken.tLPAREN); // EAT IT! - setCompletionValues(scope,CompletionKind.SINGLE_NAME_REFERENCE,KeywordSetKey.EMPTY); - IASTExpression astExpression = null; - astExpression = expression(scope, CompletionKind.SINGLE_NAME_REFERENCE, KeywordSetKey.EXPRESSION); - setCompletionValues(scope,CompletionKind.NO_SUCH_KIND,KeywordSetKey.EMPTY); - consume(IToken.tRPAREN); - d.setConstructorExpression(astExpression); - } - } - - /** * @param d */ protected void throwAwayMarksForInitializerClause(Declarator d) { - simpleDeclarationMark = null; - if( d.getNameDuple() != null ) - d.getNameDuple().getLastToken().setNext( null ); - if( d.getPointerOperatorNameDuple() != null ) - d.getPointerOperatorNameDuple().getLastToken().setNext( null ); + simpleDeclarationMark = null; + if (d.getNameDuple() != null) + d.getNameDuple().getLastToken().setNext(null); + if (d.getPointerOperatorNameDuple() != null) + d.getPointerOperatorNameDuple().getLastToken().setNext(null); } + protected void optionalCInitializer(Declarator d, + boolean constructInitializers) throws EndOfFileException, + BacktrackException { + final IASTScope scope = d.getDeclarationWrapper().getScope(); + setCompletionValues(scope, CompletionKind.NO_SUCH_KIND, + KeywordSetKey.EMPTY); + if (LT(1) == IToken.tASSIGN) { + consume(IToken.tASSIGN); + throwAwayMarksForInitializerClause(d); + setCompletionValues(scope, CompletionKind.SINGLE_NAME_REFERENCE, + KeywordSetKey.EMPTY); + d.setInitializerClause(cInitializerClause(scope, + Collections.EMPTY_LIST, constructInitializers)); + setCompletionValues(scope, CompletionKind.NO_SUCH_KIND, + KeywordSetKey.EMPTY); + } + } + /** + * @param scope + * @return + */ + protected IASTInitializerClause cInitializerClause(IASTScope scope, + List designators, boolean constructInitializers) + throws EndOfFileException, BacktrackException { + int startingOffset = LA(1).getOffset(); + if (LT(1) == IToken.tLBRACE) { + consume(IToken.tLBRACE); + List initializerList = new ArrayList(); + for (;;) { + int checkHashcode = LA(1).hashCode(); + // required at least one initializer list + // get designator list + List newDesignators = designatorList(scope); + if (newDesignators.size() != 0) + if (LT(1) == IToken.tASSIGN) + consume(IToken.tASSIGN); + IASTInitializerClause initializer = cInitializerClause(scope, + newDesignators, constructInitializers); + initializerList.add(initializer); + // can end with just a '}' + if (LT(1) == IToken.tRBRACE) + break; + // can end with ", }" + if (LT(1) == IToken.tCOMMA) + consume(IToken.tCOMMA); + if (LT(1) == IToken.tRBRACE) + break; + if (checkHashcode == LA(1).hashCode()) { + throwBacktrack(startingOffset); + return null; + } - protected void optionalCInitializer( Declarator d, boolean constructInitializers ) throws EndOfFileException, BacktrackException - { - final IASTScope scope = d.getDeclarationWrapper().getScope(); - setCompletionValues(scope,CompletionKind.NO_SUCH_KIND,KeywordSetKey.EMPTY); - if( LT(1) == IToken.tASSIGN ) - { - consume( IToken.tASSIGN ); - throwAwayMarksForInitializerClause(d); - setCompletionValues(scope,CompletionKind.SINGLE_NAME_REFERENCE,KeywordSetKey.EMPTY); - d.setInitializerClause( cInitializerClause(scope, Collections.EMPTY_LIST, constructInitializers ) ); - setCompletionValues(scope,CompletionKind.NO_SUCH_KIND,KeywordSetKey.EMPTY); - } - } - /** - * @param scope - * @return - */ - protected IASTInitializerClause cInitializerClause( - IASTScope scope, - List designators, boolean constructInitializers) - throws EndOfFileException, BacktrackException - { - if (LT(1) == IToken.tLBRACE) - { - consume(IToken.tLBRACE); - List initializerList = new ArrayList(); - for (;;) - { - int checkOffset = LA(1).hashCode(); - // required at least one initializer list - // get designator list - List newDesignators = designatorList(scope); - if( newDesignators.size() != 0 ) - if( LT(1) == IToken.tASSIGN ) - consume( IToken.tASSIGN ); - IASTInitializerClause initializer = - cInitializerClause(scope, newDesignators, constructInitializers ); - initializerList.add(initializer); - // can end with just a '}' - if (LT(1) == IToken.tRBRACE) - break; - // can end with ", }" - if (LT(1) == IToken.tCOMMA) - consume(IToken.tCOMMA); - if (LT(1) == IToken.tRBRACE) - break; - if( checkOffset == LA(1).hashCode()) - throw backtrack; - - // otherwise, its another initializer in the list - } - // consume the closing brace - consume(IToken.tRBRACE); - return createInitializerClause( - scope, - ( - ( designators.size() == 0 ) ? - IASTInitializerClause.Kind.INITIALIZER_LIST : - IASTInitializerClause.Kind.DESIGNATED_INITIALIZER_LIST ), - null, initializerList, designators, constructInitializers ); - } - // if we get this far, it means that we have not yet succeeded - // try this now instead - // assignmentExpression - try - { - IASTExpression assignmentExpression = assignmentExpression(scope, CompletionKind.SINGLE_NAME_REFERENCE, KeywordSetKey.EXPRESSION); - try - { - return createInitializerClause( - scope, - ( - ( designators.size() == 0 ) ? - IASTInitializerClause.Kind.ASSIGNMENT_EXPRESSION : - IASTInitializerClause.Kind.DESIGNATED_ASSIGNMENT_EXPRESSION ), - assignmentExpression, null, designators, constructInitializers ); - } - catch (Exception e) - { - logException( "cInitializerClause:createInitializerClause", e ); //$NON-NLS-1$ - throw backtrack; - } - } - catch (BacktrackException b) - { - // do nothing - } - throw backtrack; - } - /** - * - */ - protected IASTInitializerClause initializerClause(IASTScope scope, boolean constructInitializers) - throws EndOfFileException, BacktrackException - { - if (LT(1) == IToken.tLBRACE) - { - consume(IToken.tLBRACE); - if (LT(1) == (IToken.tRBRACE)) - { - consume(IToken.tRBRACE); - try - { - return createInitializerClause( - scope, - IASTInitializerClause.Kind.EMPTY, - null, null, Collections.EMPTY_LIST, constructInitializers ); - } - catch (Exception e) - { - logException( "initializerClause_1:createInitializerClause", e ); //$NON-NLS-1$ - throw backtrack; - } - } - - // otherwise it is a list of initializer clauses - List initializerClauses = null; - for (;;) - { - IASTInitializerClause clause = initializerClause(scope, constructInitializers); - if( clause != null ) - { - if( initializerClauses == null ) - initializerClauses = new ArrayList(); - initializerClauses.add(clause); - } - if (LT(1) == IToken.tRBRACE) - break; - consume(IToken.tCOMMA); - } - consume(IToken.tRBRACE); - try - { - return createInitializerClause( - scope, - IASTInitializerClause.Kind.INITIALIZER_LIST, - null, initializerClauses == null ? Collections.EMPTY_LIST : initializerClauses, Collections.EMPTY_LIST, constructInitializers ); - } - catch (Exception e) - { - logException( "initializerClause_2:createInitializerClause", e ); //$NON-NLS-1$ - throw backtrack; - } - } - - // if we get this far, it means that we did not - // try this now instead - // assignmentExpression - try - { - IASTExpression assignmentExpression = - assignmentExpression(scope, CompletionKind.SINGLE_NAME_REFERENCE, KeywordSetKey.EXPRESSION); - - try - { - return createInitializerClause( - scope, - IASTInitializerClause.Kind.ASSIGNMENT_EXPRESSION, - assignmentExpression, null, Collections.EMPTY_LIST, constructInitializers ); - } - catch (Exception e) - { - logException( "initializerClause_3:createInitializerClause", e ); //$NON-NLS-1$ - throw backtrack; - } - } - catch (BacktrackException b) - { + // otherwise, its another initializer in the list + } + // consume the closing brace + consume(IToken.tRBRACE); + return createInitializerClause(scope, ((designators.size() == 0) + ? IASTInitializerClause.Kind.INITIALIZER_LIST + : IASTInitializerClause.Kind.DESIGNATED_INITIALIZER_LIST), + null, initializerList, designators, constructInitializers); + } + // if we get this far, it means that we have not yet succeeded + // try this now instead + // assignmentExpression + try { + IASTExpression assignmentExpression = assignmentExpression(scope, + CompletionKind.SINGLE_NAME_REFERENCE, + KeywordSetKey.EXPRESSION); + try { + return createInitializerClause( + scope, + ((designators.size() == 0) + ? IASTInitializerClause.Kind.ASSIGNMENT_EXPRESSION + : IASTInitializerClause.Kind.DESIGNATED_ASSIGNMENT_EXPRESSION), + assignmentExpression, null, designators, + constructInitializers); + } catch (Exception e) { + logException("cInitializerClause:createInitializerClause", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + } catch (BacktrackException b) { // do nothing - } - catch ( EndOfFileException eof ) - { - - } - throw backtrack; - } - - - protected IASTInitializerClause createInitializerClause( IASTScope scope, IASTInitializerClause.Kind kind, IASTExpression expression, - List initializerClauses, List designators, boolean constructInitializer ) - { - if( ! constructInitializer ) return null; - return astFactory.createInitializerClause( - scope, - kind, - expression, initializerClauses, designators ); + } + throwBacktrack(startingOffset); + return null; } - - protected List designatorList(IASTScope scope) throws EndOfFileException, BacktrackException - { - List designatorList = Collections.EMPTY_LIST; - // designated initializers for C - - if( LT(1) == IToken.tDOT || LT(1) == IToken.tLBRACKET ) - { - - while( LT(1) == IToken.tDOT || LT(1) == IToken.tLBRACKET ) - { - IToken id = null; - IASTExpression constantExpression = null; - IASTDesignator.DesignatorKind kind = null; - - if( LT(1) == IToken.tDOT ) - { - consume( IToken.tDOT ); - id = identifier(); - kind = IASTDesignator.DesignatorKind.FIELD; - } - else if( LT(1) == IToken.tLBRACKET ) - { - IToken mark = consume( IToken.tLBRACKET ); - constantExpression = expression( scope, CompletionKind.SINGLE_NAME_REFERENCE, KeywordSetKey.EXPRESSION ); - if( LT(1) != IToken.tRBRACKET ) - { - backup( mark ); - if( extension.canHandleCDesignatorInitializer( LT(1))) - { - IASTDesignator d = extension.parseDesignator( this, scope ); - if( d != null ) - { - if( designatorList == Collections.EMPTY_LIST ) - designatorList = new ArrayList( DEFAULT_DESIGNATOR_LIST_SIZE ); - designatorList.add( d ); - } - break; - } - } - consume( IToken.tRBRACKET ); - kind = IASTDesignator.DesignatorKind.SUBSCRIPT; - } - - IASTDesignator d = - astFactory.createDesignator( kind, constantExpression, id, null ); - if( designatorList == Collections.EMPTY_LIST ) - designatorList = new ArrayList( DEFAULT_DESIGNATOR_LIST_SIZE ); - designatorList.add( d ); - - } - } - else - { - if( extension.canHandleCDesignatorInitializer( LT(1))) - { - IASTDesignator d = extension.parseDesignator( this, scope ); - if( d != null ) - { - if( designatorList == Collections.EMPTY_LIST ) - designatorList = new ArrayList( DEFAULT_DESIGNATOR_LIST_SIZE ); - designatorList.add( d ); - } - } - } + /** + * + */ + protected IASTInitializerClause initializerClause(IASTScope scope, + boolean constructInitializers) throws EndOfFileException, + BacktrackException { + if (LT(1) == IToken.tLBRACE) { + IToken t = consume(IToken.tLBRACE); + if (LT(1) == (IToken.tRBRACE)) { + consume(IToken.tRBRACE); + try { + return createInitializerClause(scope, + IASTInitializerClause.Kind.EMPTY, null, null, + Collections.EMPTY_LIST, constructInitializers); + } catch (Exception e) { + logException( + "initializerClause_1:createInitializerClause", e); //$NON-NLS-1$ + throwBacktrack(t.getOffset()); + return null; + } + } + + // otherwise it is a list of initializer clauses + List initializerClauses = null; + int startingOffset = LA(1).getOffset(); + for (;;) { + IASTInitializerClause clause = initializerClause(scope, + constructInitializers); + if (clause != null) { + if (initializerClauses == null) + initializerClauses = new ArrayList(); + initializerClauses.add(clause); + } + if (LT(1) == IToken.tRBRACE) + break; + consume(IToken.tCOMMA); + } + consume(IToken.tRBRACE); + try { + return createInitializerClause(scope, + IASTInitializerClause.Kind.INITIALIZER_LIST, null, + initializerClauses == null + ? Collections.EMPTY_LIST + : initializerClauses, Collections.EMPTY_LIST, + constructInitializers); + } catch (Exception e) { + logException("initializerClause_2:createInitializerClause", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + return null; + } + } + + // if we get this far, it means that we did not + // try this now instead + // assignmentExpression + int startingOffset = LA(1).getOffset(); + + IASTExpression assignmentExpression = assignmentExpression(scope, + CompletionKind.SINGLE_NAME_REFERENCE, + KeywordSetKey.EXPRESSION); + + try { + return createInitializerClause(scope, + IASTInitializerClause.Kind.ASSIGNMENT_EXPRESSION, + assignmentExpression, null, Collections.EMPTY_LIST, + constructInitializers); + } catch (Exception e) { + logException("initializerClause_3:createInitializerClause", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + throwBacktrack(startingOffset); + return null; + } + + protected IASTInitializerClause createInitializerClause(IASTScope scope, + IASTInitializerClause.Kind kind, IASTExpression expression, + List initializerClauses, List designators, + boolean constructInitializer) { + if (!constructInitializer) + return null; + return astFactory.createInitializerClause(scope, kind, expression, + initializerClauses, designators); + } + + protected List designatorList(IASTScope scope) throws EndOfFileException, + BacktrackException { + List designatorList = Collections.EMPTY_LIST; + // designated initializers for C + + if (LT(1) == IToken.tDOT || LT(1) == IToken.tLBRACKET) { + + while (LT(1) == IToken.tDOT || LT(1) == IToken.tLBRACKET) { + IToken id = null; + IASTExpression constantExpression = null; + IASTDesignator.DesignatorKind kind = null; + + if (LT(1) == IToken.tDOT) { + consume(IToken.tDOT); + id = identifier(); + kind = IASTDesignator.DesignatorKind.FIELD; + } else if (LT(1) == IToken.tLBRACKET) { + IToken mark = consume(IToken.tLBRACKET); + constantExpression = expression(scope, + CompletionKind.SINGLE_NAME_REFERENCE, + KeywordSetKey.EXPRESSION); + if (LT(1) != IToken.tRBRACKET) { + backup(mark); + if (extension.canHandleCDesignatorInitializer(LT(1))) { + IASTDesignator d = extension.parseDesignator(this, + scope); + if (d != null) { + if (designatorList == Collections.EMPTY_LIST) + designatorList = new ArrayList( + DEFAULT_DESIGNATOR_LIST_SIZE); + designatorList.add(d); + } + break; + } + } + consume(IToken.tRBRACKET); + kind = IASTDesignator.DesignatorKind.SUBSCRIPT; + } + + IASTDesignator d = astFactory.createDesignator(kind, + constantExpression, id, null); + if (designatorList == Collections.EMPTY_LIST) + designatorList = new ArrayList(DEFAULT_DESIGNATOR_LIST_SIZE); + designatorList.add(d); + + } + } else { + if (extension.canHandleCDesignatorInitializer(LT(1))) { + IASTDesignator d = extension.parseDesignator(this, scope); + if (d != null) { + if (designatorList == Collections.EMPTY_LIST) + designatorList = new ArrayList( + DEFAULT_DESIGNATOR_LIST_SIZE); + designatorList.add(d); + } + } + } return designatorList; - } - /** - * Parse a declarator, as according to the ANSI C++ specification. - * - * declarator - * : (ptrOperator)* directDeclarator - * - * directDeclarator - * : declaratorId - * | directDeclarator "(" parameterDeclarationClause ")" (cvQualifier)* - * (exceptionSpecification)* - * | directDeclarator "[" (constantExpression)? "]" - * | "(" declarator")" - * | directDeclarator "(" parameterDeclarationClause ")" (oldKRParameterDeclaration)* - * - * declaratorId - * : name - * - * @param container IParserCallback object that represents the owner declaration. - * @return declarator that this parsing produced. - * @throws BacktrackException request a backtrack - */ - protected Declarator declarator( - IDeclaratorOwner owner, IASTScope scope, SimpleDeclarationStrategy strategy, CompletionKind kind ) - throws EndOfFileException, BacktrackException - { - Declarator d = null; - DeclarationWrapper sdw = owner.getDeclarationWrapper(); - overallLoop : do - { - d = new Declarator(owner); - - consumePointerOperators(d); - - if (LT(1) == IToken.tLPAREN) - { - consume(); - declarator(d, scope, strategy, kind ); - consume(IToken.tRPAREN); - } - else - consumeTemplatedOperatorName(d, kind); - - for (;;) - { - switch (LT(1)) - { - case IToken.tLPAREN : - - boolean failed = false; - IASTScope parameterScope = astFactory.getDeclaratorScope( scope, d.getNameDuple() ); - // temporary fix for initializer/function declaration ambiguity - if ( queryLookaheadCapability(2) && !LA(2).looksLikeExpression() && strategy != SimpleDeclarationStrategy.TRY_VARIABLE ) - { - if( LT(2) == IToken.tIDENTIFIER ) - { + } + /** + * Parse a declarator, as according to the ANSI C++ specification. + * + * declarator : (ptrOperator)* directDeclarator + * + * directDeclarator : declaratorId | directDeclarator "(" + * parameterDeclarationClause ")" (cvQualifier)* (exceptionSpecification)* | + * directDeclarator "[" (constantExpression)? "]" | "(" declarator")" | + * directDeclarator "(" parameterDeclarationClause ")" + * (oldKRParameterDeclaration)* + * + * declaratorId : name + * + * @param container + * IParserCallback object that represents the owner declaration. + * @return declarator that this parsing produced. + * @throws BacktrackException + * request a backtrack + */ + protected Declarator declarator(IDeclaratorOwner owner, IASTScope scope, + SimpleDeclarationStrategy strategy, CompletionKind kind) + throws EndOfFileException, BacktrackException { + Declarator d = null; + DeclarationWrapper sdw = owner.getDeclarationWrapper(); + int startingOffset = LA(1).getOffset(); + overallLoop : do { + d = new Declarator(owner); + + consumePointerOperators(d); + + if (LT(1) == IToken.tLPAREN) { + consume(); + declarator(d, scope, strategy, kind); + consume(IToken.tRPAREN); + } else + consumeTemplatedOperatorName(d, kind); + + for (;;) { + switch (LT(1)) { + case IToken.tLPAREN : + + boolean failed = false; + IASTScope parameterScope = astFactory + .getDeclaratorScope(scope, d.getNameDuple()); + // temporary fix for initializer/function declaration + // ambiguity + if (queryLookaheadCapability(2) + && !LA(2).looksLikeExpression() + && strategy != SimpleDeclarationStrategy.TRY_VARIABLE) { + if (LT(2) == IToken.tIDENTIFIER) { IToken newMark = mark(); - consume( IToken.tLPAREN ); + consume(IToken.tLPAREN); ITokenDuple queryName = null; - try - { - try - { - queryName = name(parameterScope, CompletionKind.TYPE_REFERENCE, KeywordSetKey.EMPTY ); - if( ! astFactory.queryIsTypeName( parameterScope, queryName ) ) - failed = true; - } - catch (Exception e) - { - logException( "declarator:queryIsTypeName", e ); //$NON-NLS-1$ - throw backtrack; - } - } catch( BacktrackException b ) - { - failed = true; - } - - if( queryName != null ) - queryName.freeReferences(astFactory.getReferenceManager()); - backup( newMark ); - } - } - if( ( queryLookaheadCapability(2) && !LA(2).looksLikeExpression() && strategy != SimpleDeclarationStrategy.TRY_VARIABLE && !failed) || ! queryLookaheadCapability(3) ) - { - // parameterDeclarationClause - d.setIsFunction(true); - // TODO need to create a temporary scope object here - consume(IToken.tLPAREN); - setCompletionValues( scope, CompletionKind.ARGUMENT_TYPE, KeywordSetKey.DECL_SPECIFIER_SEQUENCE ); - boolean seenParameter = false; - parameterDeclarationLoop : for (;;) - { - switch (LT(1)) - { - case IToken.tRPAREN : - consume(); - setCompletionValues( parameterScope, CompletionKind.NO_SUCH_KIND, KeywordSetKey.FUNCTION_MODIFIER ); - break parameterDeclarationLoop; - case IToken.tELLIPSIS : - consume(); - d.setIsVarArgs( true ); - break; - case IToken.tCOMMA : - consume(); - setCompletionValues( parameterScope, CompletionKind.ARGUMENT_TYPE, KeywordSetKey.DECL_SPECIFIER_SEQUENCE ); - seenParameter = false; - break; - default : - if (seenParameter) - throw backtrack; - parameterDeclaration(d, parameterScope); - seenParameter = true; - } - } + try { + try { + queryName = name(parameterScope, + CompletionKind.TYPE_REFERENCE, + KeywordSetKey.EMPTY); + if (!astFactory.queryIsTypeName( + parameterScope, queryName)) + failed = true; + } catch (Exception e) { + logException( + "declarator:queryIsTypeName", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + } catch (BacktrackException b) { + failed = true; + } + + if (queryName != null) + queryName.freeReferences(astFactory + .getReferenceManager()); + backup(newMark); + } + } + if ((queryLookaheadCapability(2) + && !LA(2).looksLikeExpression() + && strategy != SimpleDeclarationStrategy.TRY_VARIABLE && !failed) + || !queryLookaheadCapability(3)) { + // parameterDeclarationClause + d.setIsFunction(true); + // TODO need to create a temporary scope object here + consume(IToken.tLPAREN); + setCompletionValues(scope, + CompletionKind.ARGUMENT_TYPE, + KeywordSetKey.DECL_SPECIFIER_SEQUENCE); + boolean seenParameter = false; + parameterDeclarationLoop : for (;;) { + switch (LT(1)) { + case IToken.tRPAREN : + consume(); + setCompletionValues(parameterScope, + CompletionKind.NO_SUCH_KIND, + KeywordSetKey.FUNCTION_MODIFIER); + break parameterDeclarationLoop; + case IToken.tELLIPSIS : + consume(); + d.setIsVarArgs(true); + break; + case IToken.tCOMMA : + consume(); + setCompletionValues( + parameterScope, + CompletionKind.ARGUMENT_TYPE, + KeywordSetKey.DECL_SPECIFIER_SEQUENCE); + seenParameter = false; + break; + default : + if (seenParameter) + throwBacktrack(startingOffset); + parameterDeclaration(d, parameterScope); + seenParameter = true; + } + } } - if (LT(1) == IToken.tCOLON || LT(1) == IToken.t_try ) - break overallLoop; - - IToken beforeCVModifier = mark(); - IToken [] cvModifiers = new IToken[2]; - int numCVModifiers = 0; - IToken afterCVModifier = beforeCVModifier; - // const-volatile - // 2 options: either this is a marker for the method, - // or it might be the beginning of old K&R style parameter declaration, see - // void getenv(name) const char * name; {} - // This will be determined further below - while( (LT(1) == IToken.t_const || LT(1) == IToken.t_volatile) && numCVModifiers < 2 ) - { - cvModifiers[numCVModifiers++] = consume(); - afterCVModifier = mark(); - } - //check for throws clause here - List exceptionSpecIds = null; - if (LT(1) == IToken.t_throw) - { - exceptionSpecIds = new ArrayList(); - consume(); // throw - consume(IToken.tLPAREN); // ( - boolean done = false; - IASTTypeId exceptionTypeId = null; - while (!done) - { - switch (LT(1)) - { - case IToken.tRPAREN : - consume(); - done = true; - break; - case IToken.tCOMMA : - consume(); - break; - default : - try - { - exceptionTypeId = typeId(scope, false, CompletionKind.EXCEPTION_REFERENCE ); - exceptionSpecIds.add(exceptionTypeId); - exceptionTypeId.acceptElement( requestor, astFactory.getReferenceManager() ); - } - catch (BacktrackException e) - { - failParse(); - consume(); - // eat this token anyway - continue; - } - break; - } - } - if (exceptionSpecIds != null) - try - { - d.setExceptionSpecification( - astFactory - .createExceptionSpecification( - d.getDeclarationWrapper().getScope(), exceptionSpecIds)); - } - catch (ASTSemanticException e) - { - failParse(); - throw backtrack; - } catch (Exception e) - { - logException( "declarator:createExceptionSpecification", e ); //$NON-NLS-1$ - throw backtrack; - } - } - // check for optional pure virtual - if (LT(1) == IToken.tASSIGN - && LT(2) == IToken.tINTEGER - && LA(2).getImage().equals("0")) //$NON-NLS-1$ - { - consume(IToken.tASSIGN); - consume(IToken.tINTEGER); - d.setPureVirtual(true); - } - if (afterCVModifier != LA(1) - || LT(1) == IToken.tSEMI) - { - // There were C++-specific clauses after const/volatile modifier - // Then it is a marker for the method - if ( numCVModifiers > 0 ) - { - for( int i = 0; i < numCVModifiers; i++ ){ - if( cvModifiers[i].getType() == IToken.t_const ) - d.setConst(true); - if( cvModifiers[i].getType() == IToken.t_volatile ) - d.setVolatile(true); - } - } - afterCVModifier = mark(); - // In this case (method) we can't expect K&R parameter declarations, - // but we'll check anyway, for errorhandling - } - break; - case IToken.tLBRACKET : - consumeArrayModifiers(d, sdw.getScope()); - continue; - case IToken.tCOLON : - consume(IToken.tCOLON); - IASTExpression exp = constantExpression(scope, CompletionKind.SINGLE_NAME_REFERENCE, KeywordSetKey.EXPRESSION ); - d.setBitFieldExpression(exp); - default : - break; - } - break; - } - if (LA(1).getType() != IToken.tIDENTIFIER) - break; + if (LT(1) == IToken.tCOLON || LT(1) == IToken.t_try) + break overallLoop; - } - while (true); - if (d.getOwner() instanceof IDeclarator) - ((Declarator)d.getOwner()).setOwnedDeclarator(d); - return d; - } - - protected void consumeTemplatedOperatorName(Declarator d, CompletionKind kind) - throws EndOfFileException, BacktrackException - { - TemplateParameterManager argumentList = TemplateParameterManager.getInstance(); - try - { - if (LT(1) == IToken.t_operator) - operatorId(d, null, null, kind); - else - { - try - { - ITokenDuple duple = name(d.getDeclarationWrapper().getScope(), kind, KeywordSetKey.EMPTY ); - d.setName(duple); - - } - catch (BacktrackException bt) - { - Declarator d1 = d; - Declarator d11 = d1; - IToken start = null; - - boolean hasTemplateId = false; - - IToken mark = mark(); - if (LT(1) == IToken.tCOLONCOLON - || LT(1) == IToken.tIDENTIFIER) - { - start = consume(); - IToken end = null; - - if (start.getType() == IToken.tIDENTIFIER){ - end = consumeTemplateArguments(d.getDeclarationWrapper().getScope(), end, argumentList, kind); - if( end != null && end.getType() == IToken.tGT ) - hasTemplateId = true; - } - - while (LT(1) == IToken.tCOLONCOLON - || LT(1) == IToken.tIDENTIFIER) - { - end = consume(); - if (end.getType() == IToken.tIDENTIFIER){ - end = consumeTemplateArguments(d.getDeclarationWrapper().getScope(), end, argumentList, kind); - if( end.getType() == IToken.tGT ) - hasTemplateId = true; - } - } - if (LT(1) == IToken.t_operator) - operatorId(d11, start, ( hasTemplateId ? argumentList : null ), kind ); - else - { - - backup(mark); - throw backtrack; - } - } - } - } - } finally - { - TemplateParameterManager.returnInstance(argumentList ); + IToken beforeCVModifier = mark(); + IToken[] cvModifiers = new IToken[2]; + int numCVModifiers = 0; + IToken afterCVModifier = beforeCVModifier; + // const-volatile + // 2 options: either this is a marker for the method, + // or it might be the beginning of old K&R style + // parameter declaration, see + // void getenv(name) const char * name; {} + // This will be determined further below + while ((LT(1) == IToken.t_const || LT(1) == IToken.t_volatile) + && numCVModifiers < 2) { + cvModifiers[numCVModifiers++] = consume(); + afterCVModifier = mark(); + } + //check for throws clause here + List exceptionSpecIds = null; + if (LT(1) == IToken.t_throw) { + exceptionSpecIds = new ArrayList(); + consume(); // throw + consume(IToken.tLPAREN); // ( + boolean done = false; + IASTTypeId exceptionTypeId = null; + while (!done) { + switch (LT(1)) { + case IToken.tRPAREN : + consume(); + done = true; + break; + case IToken.tCOMMA : + consume(); + break; + default : + try { + exceptionTypeId = typeId( + scope, + false, + CompletionKind.EXCEPTION_REFERENCE); + exceptionSpecIds + .add(exceptionTypeId); + exceptionTypeId + .acceptElement( + requestor, + astFactory + .getReferenceManager()); + } catch (BacktrackException e) { + failParse(e); + consume(); + // eat this token anyway + continue; + } + break; + } + } + if (exceptionSpecIds != null) + try { + d.setExceptionSpecification(astFactory + .createExceptionSpecification(d + .getDeclarationWrapper() + .getScope(), + exceptionSpecIds)); + } catch (ASTSemanticException e) { + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException( + "declarator:createExceptionSpecification", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + } + // check for optional pure virtual + if (LT(1) == IToken.tASSIGN && LT(2) == IToken.tINTEGER + && LA(2).getImage().equals("0")) //$NON-NLS-1$ + { + consume(IToken.tASSIGN); + consume(IToken.tINTEGER); + d.setPureVirtual(true); + } + if (afterCVModifier != LA(1) || LT(1) == IToken.tSEMI) { + // There were C++-specific clauses after + // const/volatile modifier + // Then it is a marker for the method + if (numCVModifiers > 0) { + for (int i = 0; i < numCVModifiers; i++) { + if (cvModifiers[i].getType() == IToken.t_const) + d.setConst(true); + if (cvModifiers[i].getType() == IToken.t_volatile) + d.setVolatile(true); + } + } + afterCVModifier = mark(); + // In this case (method) we can't expect K&R + // parameter declarations, + // but we'll check anyway, for errorhandling + } + break; + case IToken.tLBRACKET : + consumeArrayModifiers(d, sdw.getScope()); + continue; + case IToken.tCOLON : + consume(IToken.tCOLON); + IASTExpression exp = constantExpression(scope, + CompletionKind.SINGLE_NAME_REFERENCE, + KeywordSetKey.EXPRESSION); + d.setBitFieldExpression(exp); + default : + break; + } + break; + } + if (LA(1).getType() != IToken.tIDENTIFIER) + break; + + } while (true); + if (d.getOwner() instanceof IDeclarator) + ((Declarator) d.getOwner()).setOwnedDeclarator(d); + return d; + } + + protected void consumeTemplatedOperatorName(Declarator d, + CompletionKind kind) throws EndOfFileException, BacktrackException { + TemplateParameterManager argumentList = TemplateParameterManager + .getInstance(); + try { + if (LT(1) == IToken.t_operator) + operatorId(d, null, null, kind); + else { + try { + ITokenDuple duple = name(d.getDeclarationWrapper() + .getScope(), kind, KeywordSetKey.EMPTY); + d.setName(duple); + + } catch (BacktrackException bt) { + Declarator d1 = d; + Declarator d11 = d1; + IToken start = null; + + boolean hasTemplateId = false; + + IToken mark = mark(); + if (LT(1) == IToken.tCOLONCOLON + || LT(1) == IToken.tIDENTIFIER) { + start = consume(); + IToken end = null; + + if (start.getType() == IToken.tIDENTIFIER) { + end = consumeTemplateArguments(d + .getDeclarationWrapper().getScope(), end, + argumentList, kind); + if (end != null && end.getType() == IToken.tGT) + hasTemplateId = true; + } + + while (LT(1) == IToken.tCOLONCOLON + || LT(1) == IToken.tIDENTIFIER) { + end = consume(); + if (end.getType() == IToken.tIDENTIFIER) { + end = consumeTemplateArguments(d + .getDeclarationWrapper().getScope(), + end, argumentList, kind); + if (end.getType() == IToken.tGT) + hasTemplateId = true; + } + } + if (LT(1) == IToken.t_operator) + operatorId(d11, start, (hasTemplateId + ? argumentList + : null), kind); + else { + + backup(mark); + throwBacktrack(mark.getOffset()); + } + } + } + } + } finally { + TemplateParameterManager.returnInstance(argumentList); } - } - /** - * Parse an enumeration specifier, as according to the ANSI specs in C & C++. - * - * enumSpecifier: - * "enum" (name)? "{" (enumerator-list) "}" - * enumerator-list: - * enumerator-definition - * enumerator-list , enumerator-definition - * enumerator-definition: - * enumerator - * enumerator = constant-expression - * enumerator: identifier - * - * @param owner IParserCallback object that represents the declaration that owns this type specifier. - * @throws BacktrackException request a backtrack - */ - protected void enumSpecifier(DeclarationWrapper sdw) - throws BacktrackException, EndOfFileException - { - IToken mark = mark(); - IToken identifier = null; - consume( IToken.t_enum ); - setCompletionValues( sdw.getScope(), CompletionKind.ENUM_REFERENCE ); - if (LT(1) == IToken.tIDENTIFIER) - { - identifier = identifier(); - setCompletionValues( sdw.getScope(), CompletionKind.ENUM_REFERENCE ); - } - if (LT(1) == IToken.tLBRACE) - { - IASTEnumerationSpecifier enumeration = null; - try - { - enumeration = astFactory.createEnumerationSpecifier( - sdw.getScope(), - ((identifier == null) ? "" : identifier.getImage()), //$NON-NLS-1$ - mark.getOffset(), - mark.getLineNumber(), - ((identifier == null) - ? mark.getOffset() - : identifier.getOffset()), - ((identifier == null)? mark.getEndOffset() : identifier.getEndOffset()), - ((identifier == null)? mark.getLineNumber() : identifier.getLineNumber()) - ); - } - catch (ASTSemanticException e) - { - failParse(); - throw backtrack; - } catch (Exception e) - { - logException( "enumSpecifier:createEnumerationSpecifier", e ); //$NON-NLS-1$ - throw backtrack; - } - consume(IToken.tLBRACE); - while (LT(1) != IToken.tRBRACE) - { - IToken enumeratorIdentifier = null; - if (LT(1) == IToken.tIDENTIFIER) - { - enumeratorIdentifier = identifier(); - } - else - { - throw backtrack; - } - IASTExpression initialValue = null; - if (LT(1) == IToken.tASSIGN) - { - consume(IToken.tASSIGN); - initialValue = constantExpression(sdw.getScope(), CompletionKind.SINGLE_NAME_REFERENCE, KeywordSetKey.EXPRESSION); - } - IASTEnumerator enumerator = null; - if (LT(1) == IToken.tRBRACE) - { - try - { - enumerator = astFactory.addEnumerator( - enumeration, - enumeratorIdentifier.getImage(), - enumeratorIdentifier.getOffset(), - enumeratorIdentifier.getLineNumber(), - enumeratorIdentifier.getOffset(), enumeratorIdentifier.getEndOffset(), - enumeratorIdentifier.getLineNumber(), lastToken.getEndOffset(), lastToken.getLineNumber(), initialValue); - endEnumerator(enumerator); - } - catch (ASTSemanticException e1) - { - failParse(); - throw backtrack; - } catch (Exception e) - { - logException( "enumSpecifier:addEnumerator", e ); //$NON-NLS-1$ - throw backtrack; - } - break; - } - if (LT(1) != IToken.tCOMMA) - { - enumeration.freeReferences( astFactory.getReferenceManager() ); - if( enumerator != null ) - enumerator.freeReferences( astFactory.getReferenceManager() ); - throw backtrack; - } - try - { - enumerator = astFactory.addEnumerator( - enumeration, - enumeratorIdentifier.getImage(), - enumeratorIdentifier.getOffset(), - enumeratorIdentifier.getLineNumber(), - enumeratorIdentifier.getOffset(), enumeratorIdentifier.getEndOffset(), enumeratorIdentifier.getLineNumber(), lastToken.getEndOffset(), lastToken.getLineNumber(), initialValue); - endEnumerator(enumerator); - } - catch (ASTSemanticException e1) - { - failParse(); - throw backtrack; - } catch (Exception e) - { - logException( "enumSpecifier:addEnumerator", e ); //$NON-NLS-1$ - throw backtrack; - } - consume(IToken.tCOMMA); - } - IToken t = consume(IToken.tRBRACE); - enumeration.setEndingOffsetAndLineNumber(t.getEndOffset(), t.getLineNumber()); - enumeration.acceptElement( requestor, astFactory.getReferenceManager() ); - handleEnumeration( enumeration ); - sdw.setTypeSpecifier(enumeration); - } - else - { - // enumSpecifierAbort - backup(mark); - throw backtrack; - } - } - + } /** - * Parse a class/struct/union definition. - * - * classSpecifier - * : classKey name (baseClause)? "{" (memberSpecification)* "}" - * - * @param owner IParserCallback object that represents the declaration that owns this classSpecifier - * @throws BacktrackException request a backtrack - */ - protected void classSpecifier(DeclarationWrapper sdw) - throws BacktrackException, EndOfFileException - { - ClassNameType nameType = ClassNameType.IDENTIFIER; - ASTClassKind classKind = null; - CompletionKind completionKind = null; - ASTAccessVisibility access = ASTAccessVisibility.PUBLIC; - IToken classKey = null; - IToken mark = mark(); - - // class key - switch (LT(1)) - { - case IToken.t_class : - classKey = consume(); - classKind = ASTClassKind.CLASS; - access = ASTAccessVisibility.PRIVATE; - completionKind = CompletionKind.CLASS_REFERENCE; - break; - case IToken.t_struct : - classKey = consume(); - classKind = ASTClassKind.STRUCT; - completionKind = CompletionKind.STRUCT_REFERENCE; - break; - case IToken.t_union : - classKey = consume(); - classKind = ASTClassKind.UNION; - completionKind = CompletionKind.UNION_REFERENCE; - break; - default : - throw backtrack; - } + * Parse an enumeration specifier, as according to the ANSI specs in C & + * C++. + * + * enumSpecifier: "enum" (name)? "{" (enumerator-list) "}" enumerator-list: + * enumerator-definition enumerator-list , enumerator-definition + * enumerator-definition: enumerator enumerator = constant-expression + * enumerator: identifier + * + * @param owner + * IParserCallback object that represents the declaration that + * owns this type specifier. + * @throws BacktrackException + * request a backtrack + */ + protected void enumSpecifier(DeclarationWrapper sdw) + throws BacktrackException, EndOfFileException { + IToken mark = mark(); + IToken identifier = null; + consume(IToken.t_enum); + setCompletionValues(sdw.getScope(), CompletionKind.ENUM_REFERENCE); + if (LT(1) == IToken.tIDENTIFIER) { + identifier = identifier(); + setCompletionValues(sdw.getScope(), CompletionKind.ENUM_REFERENCE); + } + if (LT(1) == IToken.tLBRACE) { + IASTEnumerationSpecifier enumeration = null; + try { + enumeration = astFactory.createEnumerationSpecifier(sdw + .getScope(), ((identifier == null) + ? "" : identifier.getImage()), //$NON-NLS-1$ + mark.getOffset(), mark.getLineNumber(), + ((identifier == null) ? mark.getOffset() : identifier + .getOffset()), ((identifier == null) ? mark + .getEndOffset() : identifier.getEndOffset()), + ((identifier == null) + ? mark.getLineNumber() + : identifier.getLineNumber())); + } catch (ASTSemanticException e) { + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException("enumSpecifier:createEnumerationSpecifier", e); //$NON-NLS-1$ + throwBacktrack(mark.getOffset()); + } + handleEnumeration( enumeration ); + consume(IToken.tLBRACE); + while (LT(1) != IToken.tRBRACE) { + IToken enumeratorIdentifier = null; + if (LT(1) == IToken.tIDENTIFIER) { + enumeratorIdentifier = identifier(); + } else { + throwBacktrack(LA(1).getOffset()); + } + IASTExpression initialValue = null; + if (LT(1) == IToken.tASSIGN) { + consume(IToken.tASSIGN); + initialValue = constantExpression(sdw.getScope(), + CompletionKind.SINGLE_NAME_REFERENCE, + KeywordSetKey.EXPRESSION); + } + IASTEnumerator enumerator = null; + if (LT(1) == IToken.tRBRACE) { + try { + enumerator = astFactory.addEnumerator(enumeration, + enumeratorIdentifier.getImage(), + enumeratorIdentifier.getOffset(), + enumeratorIdentifier.getLineNumber(), + enumeratorIdentifier.getOffset(), + enumeratorIdentifier.getEndOffset(), + enumeratorIdentifier.getLineNumber(), lastToken + .getEndOffset(), lastToken + .getLineNumber(), initialValue); + endEnumerator(enumerator); + } catch (ASTSemanticException e1) { + throwBacktrack(e1.getProblem()); + } catch (Exception e) { + logException("enumSpecifier:addEnumerator", e); //$NON-NLS-1$ + throwBacktrack(mark.getOffset()); + } + break; + } + if (LT(1) != IToken.tCOMMA) { + enumeration + .freeReferences(astFactory.getReferenceManager()); + if (enumerator != null) + enumerator.freeReferences(astFactory + .getReferenceManager()); + throwBacktrack(mark.getOffset()); + } + try { + enumerator = astFactory.addEnumerator(enumeration, + enumeratorIdentifier.getImage(), + enumeratorIdentifier.getOffset(), + enumeratorIdentifier.getLineNumber(), + enumeratorIdentifier.getOffset(), + enumeratorIdentifier.getEndOffset(), + enumeratorIdentifier.getLineNumber(), lastToken + .getEndOffset(), lastToken.getLineNumber(), + initialValue); + endEnumerator(enumerator); + } catch (ASTSemanticException e1) { + throwBacktrack(e1.getProblem()); + } catch (Exception e) { + logException("enumSpecifier:addEnumerator", e); //$NON-NLS-1$ + throwBacktrack(mark.getOffset()); + } + consume(IToken.tCOMMA); + } + IToken t = consume(IToken.tRBRACE); + enumeration.setEndingOffsetAndLineNumber(t.getEndOffset(), t + .getLineNumber()); + enumeration.acceptElement(requestor, astFactory + .getReferenceManager()); + sdw.setTypeSpecifier(enumeration); + } else { + // enumSpecifierAbort + backup(mark); + throwBacktrack(mark.getOffset()); + } + } + /** + * Parse a class/struct/union definition. + * + * classSpecifier : classKey name (baseClause)? "{" (memberSpecification)* + * "}" + * + * @param owner + * IParserCallback object that represents the declaration that + * owns this classSpecifier + * @throws BacktrackException + * request a backtrack + */ + protected void classSpecifier(DeclarationWrapper sdw) + throws BacktrackException, EndOfFileException { + ClassNameType nameType = ClassNameType.IDENTIFIER; + ASTClassKind classKind = null; + CompletionKind completionKind = null; + ASTAccessVisibility access = ASTAccessVisibility.PUBLIC; + IToken classKey = null; + IToken mark = mark(); - - ITokenDuple duple = null; - - setCompletionValues(sdw.getScope(), completionKind, KeywordSetKey.EMPTY ); - // class name - if (LT(1) == IToken.tIDENTIFIER) - duple = name( sdw.getScope(), completionKind, KeywordSetKey.EMPTY ); - if (duple != null && !duple.isIdentifier()) - nameType = ClassNameType.TEMPLATE; - if (LT(1) != IToken.tCOLON && LT(1) != IToken.tLBRACE) - { - backup(mark); - throw backtrack; - } - IASTClassSpecifier astClassSpecifier = null; - - try - { - astClassSpecifier = - astFactory - .createClassSpecifier( - sdw.getScope(), - duple, - classKind, - nameType, - access, - classKey.getOffset(), - classKey.getLineNumber(), - duple == null ? classKey.getOffset() : duple.getFirstToken().getOffset(), - duple == null ? classKey.getEndOffset() : duple.getFirstToken().getEndOffset(), - duple == null ? classKey.getLineNumber() : duple.getFirstToken().getLineNumber() ); - } - catch (ASTSemanticException e) - { - failParse(); - throw backtrack; - } catch (Exception e) - { - logException( "classSpecifier:createClassSpecifier", e ); //$NON-NLS-1$ - throw backtrack; - } - sdw.setTypeSpecifier(astClassSpecifier); - // base clause - if (LT(1) == IToken.tCOLON) - { - baseSpecifier(astClassSpecifier); - } - if (LT(1) == IToken.tLBRACE) - { - consume(IToken.tLBRACE); - setCompletionValues(astClassSpecifier, CompletionKind.FIELD_TYPE, KeywordSetKey.MEMBER ); - astClassSpecifier.enterScope( requestor, astFactory.getReferenceManager() ); - handleClassSpecifier( astClassSpecifier ); - memberDeclarationLoop : while (LT(1) != IToken.tRBRACE) - { - int checkToken = LA(1).hashCode(); - switch (LT(1)) - { - case IToken.t_public : - consume(); + // class key + switch (LT(1)) { + case IToken.t_class : + classKey = consume(); + classKind = ASTClassKind.CLASS; + access = ASTAccessVisibility.PRIVATE; + completionKind = CompletionKind.CLASS_REFERENCE; + break; + case IToken.t_struct : + classKey = consume(); + classKind = ASTClassKind.STRUCT; + completionKind = CompletionKind.STRUCT_REFERENCE; + break; + case IToken.t_union : + classKey = consume(); + classKind = ASTClassKind.UNION; + completionKind = CompletionKind.UNION_REFERENCE; + break; + default : + throwBacktrack(mark.getOffset()); + } + + ITokenDuple duple = null; + + setCompletionValues(sdw.getScope(), completionKind, KeywordSetKey.EMPTY); + // class name + if (LT(1) == IToken.tIDENTIFIER) + duple = name(sdw.getScope(), completionKind, KeywordSetKey.EMPTY); + if (duple != null && !duple.isIdentifier()) + nameType = ClassNameType.TEMPLATE; + if (LT(1) != IToken.tCOLON && LT(1) != IToken.tLBRACE) { + backup(mark); + throwBacktrack(mark.getOffset()); + } + IASTClassSpecifier astClassSpecifier = null; + + try { + astClassSpecifier = astFactory.createClassSpecifier(sdw.getScope(), + duple, classKind, nameType, access, classKey.getOffset(), + classKey.getLineNumber(), duple == null ? classKey + .getOffset() : duple.getFirstToken().getOffset(), + duple == null ? classKey.getEndOffset() : duple + .getFirstToken().getEndOffset(), duple == null + ? classKey.getLineNumber() + : duple.getFirstToken().getLineNumber()); + } catch (ASTSemanticException e) { + throwBacktrack(e.getProblem()); + } catch (Exception e) { + logException("classSpecifier:createClassSpecifier", e); //$NON-NLS-1$ + throwBacktrack(mark.getOffset()); + } + sdw.setTypeSpecifier(astClassSpecifier); + // base clause + if (LT(1) == IToken.tCOLON) { + baseSpecifier(astClassSpecifier); + } + if (LT(1) == IToken.tLBRACE) { + consume(IToken.tLBRACE); + setCompletionValues(astClassSpecifier, CompletionKind.FIELD_TYPE, + KeywordSetKey.MEMBER); + astClassSpecifier.enterScope(requestor, astFactory + .getReferenceManager()); + handleClassSpecifier(astClassSpecifier); + memberDeclarationLoop : while (LT(1) != IToken.tRBRACE) { + int checkToken = LA(1).hashCode(); + switch (LT(1)) { + case IToken.t_public : + consume(); consume(IToken.tCOLON); - astClassSpecifier.setCurrentVisibility( ASTAccessVisibility.PUBLIC ); - break; - case IToken.t_protected : - consume(); + astClassSpecifier + .setCurrentVisibility(ASTAccessVisibility.PUBLIC); + break; + case IToken.t_protected : + consume(); consume(IToken.tCOLON); - astClassSpecifier.setCurrentVisibility( ASTAccessVisibility.PROTECTED); + astClassSpecifier + .setCurrentVisibility(ASTAccessVisibility.PROTECTED); break; - case IToken.t_private : - consume(); - consume(IToken.tCOLON); - astClassSpecifier.setCurrentVisibility( ASTAccessVisibility.PRIVATE); - break; - case IToken.tRBRACE : - consume(IToken.tRBRACE); - break memberDeclarationLoop; - default : - try - { - declaration(astClassSpecifier, null, null, KeywordSetKey.MEMBER); - } - catch (BacktrackException bt) - { - failParse(); - if (checkToken == LA(1).hashCode()) - errorHandling(); - } - } - if (checkToken == LA(1).hashCode()) - errorHandling(); - } - // consume the } - IToken lt = consume(IToken.tRBRACE); - astClassSpecifier.setEndingOffsetAndLineNumber(lt.getEndOffset(), lt.getLineNumber()); - - try - { - astFactory.signalEndOfClassSpecifier( astClassSpecifier ); - } - catch (Exception e1) - { - logException( "classSpecifier:signalEndOfClassSpecifier", e1 ); //$NON-NLS-1$ - throw backtrack; - } - - astClassSpecifier.exitScope( requestor, astFactory.getReferenceManager() ); - - - } - } + case IToken.t_private : + consume(); + consume(IToken.tCOLON); + astClassSpecifier + .setCurrentVisibility(ASTAccessVisibility.PRIVATE); + break; + case IToken.tRBRACE : + consume(IToken.tRBRACE); + break memberDeclarationLoop; + default : + try { + declaration(astClassSpecifier, null, null, + KeywordSetKey.MEMBER); + } catch (BacktrackException bt) { + if (checkToken == LA(1).hashCode()) + errorHandling(); + } + } + if (checkToken == LA(1).hashCode()) + errorHandling(); + } + // consume the } + IToken lt = consume(IToken.tRBRACE); + astClassSpecifier.setEndingOffsetAndLineNumber(lt.getEndOffset(), + lt.getLineNumber()); + + try { + astFactory.signalEndOfClassSpecifier(astClassSpecifier); + } catch (Exception e1) { + logException("classSpecifier:signalEndOfClassSpecifier", e1); //$NON-NLS-1$ + throwBacktrack(lt.getOffset()); + } + + astClassSpecifier.exitScope(requestor, astFactory + .getReferenceManager()); + + } + } /** * Parse the subclass-baseclauses for a class specification. * @@ -2828,528 +2791,532 @@ public abstract class Parser extends ExpressionParser implements IParser * @param classSpecOwner * @throws BacktrackException */ - protected void baseSpecifier( - IASTClassSpecifier astClassSpec) - throws EndOfFileException, BacktrackException - { - consume(IToken.tCOLON); - - setCompletionValues(astClassSpec.getOwnerScope(), CompletionKind.CLASS_REFERENCE, KeywordSetKey.BASE_SPECIFIER ); - boolean isVirtual = false; - ASTAccessVisibility visibility = ASTAccessVisibility.PUBLIC; - ITokenDuple nameDuple = null; - - ArrayList bases = null; - - baseSpecifierLoop : for (;;) - { - switch (LT(1)) - { - case IToken.t_virtual : - consume(IToken.t_virtual); - setCompletionValues(astClassSpec.getOwnerScope(), CompletionKind.CLASS_REFERENCE, KeywordSetKey.EMPTY ); - isVirtual = true; - break; - case IToken.t_public : - consume(); - setCompletionValues(astClassSpec.getOwnerScope(), CompletionKind.CLASS_REFERENCE, KeywordSetKey.EMPTY ); - break; - case IToken.t_protected : - consume(); - visibility = ASTAccessVisibility.PROTECTED; - setCompletionValues(astClassSpec.getOwnerScope(), CompletionKind.CLASS_REFERENCE, KeywordSetKey.EMPTY ); - break; - case IToken.t_private : - visibility = ASTAccessVisibility.PRIVATE; - consume(); - setCompletionValues(astClassSpec.getOwnerScope(), CompletionKind.CLASS_REFERENCE, KeywordSetKey.EMPTY ); - break; - case IToken.tCOLONCOLON : - case IToken.tIDENTIFIER : - //to get templates right we need to use the class as the scope - nameDuple = name(astClassSpec, CompletionKind.CLASS_REFERENCE, KeywordSetKey.BASE_SPECIFIER ); - break; - case IToken.tCOMMA : - //because we are using the class as the scope to get the name, we need to postpone adding the base - //specifiers until after we have all the nameDuples - if( bases == null ){ - bases = new ArrayList(5); - } - bases.add( new Object[] { isVirtual ? Boolean.TRUE : Boolean.FALSE, visibility, nameDuple } ); + protected void baseSpecifier( + IASTClassSpecifier astClassSpec) + throws EndOfFileException, BacktrackException + { + int startingOffset = consume(IToken.tCOLON).getOffset(); + + setCompletionValues(astClassSpec.getOwnerScope(), CompletionKind.CLASS_REFERENCE, KeywordSetKey.BASE_SPECIFIER ); + boolean isVirtual = false; + ASTAccessVisibility visibility = ASTAccessVisibility.PUBLIC; + ITokenDuple nameDuple = null; + + ArrayList bases = null; + + baseSpecifierLoop : for (;;) + { + switch (LT(1)) + { + case IToken.t_virtual : + consume(IToken.t_virtual); + setCompletionValues(astClassSpec.getOwnerScope(), CompletionKind.CLASS_REFERENCE, KeywordSetKey.EMPTY ); + isVirtual = true; + break; + case IToken.t_public : + consume(); + setCompletionValues(astClassSpec.getOwnerScope(), CompletionKind.CLASS_REFERENCE, KeywordSetKey.EMPTY ); + break; + case IToken.t_protected : + consume(); + visibility = ASTAccessVisibility.PROTECTED; + setCompletionValues(astClassSpec.getOwnerScope(), CompletionKind.CLASS_REFERENCE, KeywordSetKey.EMPTY ); + break; + case IToken.t_private : + visibility = ASTAccessVisibility.PRIVATE; + consume(); + setCompletionValues(astClassSpec.getOwnerScope(), CompletionKind.CLASS_REFERENCE, KeywordSetKey.EMPTY ); + break; + case IToken.tCOLONCOLON : + case IToken.tIDENTIFIER : + //to get templates right we need to use the class as the scope + nameDuple = name(astClassSpec, CompletionKind.CLASS_REFERENCE, KeywordSetKey.BASE_SPECIFIER ); + break; + case IToken.tCOMMA : + //because we are using the class as the scope to get the name, we need to postpone adding the base + //specifiers until after we have all the nameDuples + if( bases == null ){ + bases = new ArrayList(4); + } + bases.add( new Object[] { isVirtual ? Boolean.TRUE : Boolean.FALSE, visibility, nameDuple } ); - isVirtual = false; - visibility = ASTAccessVisibility.PUBLIC; - nameDuple = null; - consume(); - setCompletionValues(astClassSpec.getOwnerScope(), CompletionKind.CLASS_REFERENCE, KeywordSetKey.BASE_SPECIFIER ); - continue baseSpecifierLoop; - default : - break baseSpecifierLoop; - } - } + isVirtual = false; + visibility = ASTAccessVisibility.PUBLIC; + nameDuple = null; + consume(); + setCompletionValues(astClassSpec.getOwnerScope(), CompletionKind.CLASS_REFERENCE, KeywordSetKey.BASE_SPECIFIER ); + continue baseSpecifierLoop; + default : + break baseSpecifierLoop; + } + } - try - { - if( bases != null ){ - int size = bases.size(); - for( int i = 0; i < size; i++ ){ - Object [] data = (Object[]) bases.get( i ); - astFactory.addBaseSpecifier( astClassSpec, - ((Boolean)data[0]).booleanValue(), - (ASTAccessVisibility) data[1], - (ITokenDuple)data[2] ); - } - } - - astFactory.addBaseSpecifier( - astClassSpec, - isVirtual, - visibility, - nameDuple ); - } - catch (ASTSemanticException e) - { - failParse(); - throw backtrack; - } catch (Exception e) - { - logException( "baseSpecifier_2::addBaseSpecifier", e ); //$NON-NLS-1$ - throw backtrack; - } - } - /** - * Parses a function body. - * - * @throws BacktrackException request a backtrack - */ - protected void functionBody( IASTScope scope ) throws EndOfFileException, BacktrackException - { - compoundStatement( scope, false ); - } - /** - * Parses a statement. - * - * @throws BacktrackException request a backtrack - */ - protected void statement(IASTCodeScope scope) throws EndOfFileException, BacktrackException - { - - setCompletionValues(scope, CompletionKind.SINGLE_NAME_REFERENCE, KeywordSetKey.STATEMENT); - - switch (LT(1)) - { - case IToken.t_case : - consume(IToken.t_case); - IASTExpression constant_expression = constantExpression(scope, CompletionKind.SINGLE_NAME_REFERENCE, KeywordSetKey.EXPRESSION ); - constant_expression.acceptElement(requestor, astFactory.getReferenceManager()); + try + { + if( bases != null ){ + int size = bases.size(); + for( int i = 0; i < size; i++ ){ + Object [] data = (Object[]) bases.get( i ); + astFactory.addBaseSpecifier( astClassSpec, + ((Boolean)data[0]).booleanValue(), + (ASTAccessVisibility) data[1], + (ITokenDuple)data[2] ); + } + } + + astFactory.addBaseSpecifier( + astClassSpec, + isVirtual, + visibility, + nameDuple ); + } + catch (ASTSemanticException e) + { + failParse(); + throwBacktrack(e.getProblem()); + } catch (Exception e) + { + logException( "baseSpecifier_2::addBaseSpecifier", e ); //$NON-NLS-1$ + throwBacktrack( startingOffset ); + } + } + + /** + * Parses a function body. + * + * @throws BacktrackException + * request a backtrack + */ + protected void functionBody(IASTScope scope) throws EndOfFileException, + BacktrackException { + compoundStatement(scope, false); + } + /** + * Parses a statement. + * + * @throws BacktrackException + * request a backtrack + */ + protected void statement(IASTCodeScope scope) throws EndOfFileException, + BacktrackException { + + setCompletionValues(scope, CompletionKind.SINGLE_NAME_REFERENCE, + KeywordSetKey.STATEMENT); + + switch (LT(1)) { + case IToken.t_case : + consume(IToken.t_case); + IASTExpression constant_expression = constantExpression(scope, + CompletionKind.SINGLE_NAME_REFERENCE, + KeywordSetKey.EXPRESSION); + constant_expression.acceptElement(requestor, astFactory + .getReferenceManager()); endExpression(constant_expression); - consume(IToken.tCOLON); - statement(scope); - cleanupLastToken(); - return; - case IToken.t_default : - consume(IToken.t_default); - consume(IToken.tCOLON); - statement(scope); - cleanupLastToken(); - return; - case IToken.tLBRACE : - compoundStatement(scope, true); - cleanupLastToken(); - return; - case IToken.t_if : - consume( IToken.t_if ); - consume(IToken.tLPAREN); - condition( scope ); - consume(IToken.tRPAREN); - if( LT(1) != IToken.tLBRACE ) - singleStatementScope(scope); - else - statement( scope ); - if (LT(1) == IToken.t_else) - { - consume( IToken.t_else ); - if( LT(1) == IToken.t_if ){ - //an else if, return and get the rest of the else if as the next statement instead of recursing - cleanupLastToken(); - return; - } else if( LT(1) != IToken.tLBRACE ) - singleStatementScope(scope); - else - statement( scope ); - } - cleanupLastToken(); - return; - case IToken.t_switch : - consume(); - consume(IToken.tLPAREN); - condition(scope); - consume(IToken.tRPAREN); - statement(scope); - cleanupLastToken(); - return; - case IToken.t_while : - consume(IToken.t_while); - consume(IToken.tLPAREN); - condition(scope); - consume(IToken.tRPAREN); - if( LT(1) != IToken.tLBRACE ) - singleStatementScope(scope); - else - statement(scope); - cleanupLastToken(); - return; - case IToken.t_do : - consume(IToken.t_do); - if( LT(1) != IToken.tLBRACE ) + consume(IToken.tCOLON); + statement(scope); + cleanupLastToken(); + return; + case IToken.t_default : + consume(IToken.t_default); + consume(IToken.tCOLON); + statement(scope); + cleanupLastToken(); + return; + case IToken.tLBRACE : + compoundStatement(scope, true); + cleanupLastToken(); + return; + case IToken.t_if : + consume(IToken.t_if); + consume(IToken.tLPAREN); + condition(scope); + consume(IToken.tRPAREN); + if (LT(1) != IToken.tLBRACE) singleStatementScope(scope); else statement(scope); - consume(IToken.t_while); - consume(IToken.tLPAREN); - condition(scope); - consume(IToken.tRPAREN); - cleanupLastToken(); - return; - case IToken.t_for : - consume(); - consume(IToken.tLPAREN); - forInitStatement(scope); - if (LT(1) != IToken.tSEMI) - condition(scope); - consume(IToken.tSEMI); - if (LT(1) != IToken.tRPAREN) - { - IASTExpression finalExpression = expression(scope, CompletionKind.SINGLE_NAME_REFERENCE, KeywordSetKey.DECLARATION); - finalExpression.acceptElement(requestor, astFactory.getReferenceManager()); - endExpression(finalExpression); - } - consume(IToken.tRPAREN); - statement(scope); - cleanupLastToken(); - return; - case IToken.t_break : - consume(); - consume(IToken.tSEMI); - cleanupLastToken(); - return; - case IToken.t_continue : - consume(); - consume(IToken.tSEMI); - cleanupLastToken(); - return; - case IToken.t_return : - consume(); - if (LT(1) != IToken.tSEMI) - { - IASTExpression retVal = expression(scope, CompletionKind.SINGLE_NAME_REFERENCE, KeywordSetKey.EXPRESSION); - retVal.acceptElement(requestor, astFactory.getReferenceManager()); - endExpression(retVal); - } - consume(IToken.tSEMI); - cleanupLastToken(); - return; - case IToken.t_goto : - consume(); - consume(IToken.tIDENTIFIER); - consume(IToken.tSEMI); - cleanupLastToken(); - return; - case IToken.t_try : - consume(); - compoundStatement(scope,true); - catchHandlerSequence(scope); - cleanupLastToken(); - return; - case IToken.tSEMI : - consume(); - cleanupLastToken(); - return; - default : - // can be many things: - // label - - if (queryLookaheadCapability(2) && LT(1) == IToken.tIDENTIFIER && LT(2) == IToken.tCOLON) - { - consume(IToken.tIDENTIFIER); - consume(IToken.tCOLON); - statement(scope); - cleanupLastToken(); - return; - } - // expressionStatement - // Note: the function style cast ambiguity is handled in expression - // Since it only happens when we are in a statement - IToken mark = mark(); - IASTExpression expressionStatement = null; - try - { - expressionStatement = expression(scope, CompletionKind.SINGLE_NAME_REFERENCE, KeywordSetKey.STATEMENT); - consume(IToken.tSEMI); - expressionStatement.acceptElement( requestor, astFactory.getReferenceManager() ); - endExpression(expressionStatement); - return; - } - catch (BacktrackException b) - { - backup( mark ); - if( expressionStatement != null ) - expressionStatement.freeReferences(astFactory.getReferenceManager()); - } + if (LT(1) == IToken.t_else) { + consume(IToken.t_else); + if (LT(1) == IToken.t_if) { + //an else if, return and get the rest of the else if as + // the next statement instead of recursing + cleanupLastToken(); + return; + } else if (LT(1) != IToken.tLBRACE) + singleStatementScope(scope); + else + statement(scope); + } + cleanupLastToken(); + return; + case IToken.t_switch : + consume(); + consume(IToken.tLPAREN); + condition(scope); + consume(IToken.tRPAREN); + statement(scope); + cleanupLastToken(); + return; + case IToken.t_while : + consume(IToken.t_while); + consume(IToken.tLPAREN); + condition(scope); + consume(IToken.tRPAREN); + if (LT(1) != IToken.tLBRACE) + singleStatementScope(scope); + else + statement(scope); + cleanupLastToken(); + return; + case IToken.t_do : + consume(IToken.t_do); + if (LT(1) != IToken.tLBRACE) + singleStatementScope(scope); + else + statement(scope); + consume(IToken.t_while); + consume(IToken.tLPAREN); + condition(scope); + consume(IToken.tRPAREN); + cleanupLastToken(); + return; + case IToken.t_for : + consume(); + consume(IToken.tLPAREN); + forInitStatement(scope); + if (LT(1) != IToken.tSEMI) + condition(scope); + consume(IToken.tSEMI); + if (LT(1) != IToken.tRPAREN) { + IASTExpression finalExpression = expression(scope, + CompletionKind.SINGLE_NAME_REFERENCE, + KeywordSetKey.DECLARATION); + finalExpression.acceptElement(requestor, astFactory + .getReferenceManager()); + endExpression(finalExpression); + } + consume(IToken.tRPAREN); + statement(scope); + cleanupLastToken(); + return; + case IToken.t_break : + consume(); + consume(IToken.tSEMI); + cleanupLastToken(); + return; + case IToken.t_continue : + consume(); + consume(IToken.tSEMI); + cleanupLastToken(); + return; + case IToken.t_return : + consume(); + if (LT(1) != IToken.tSEMI) { + IASTExpression retVal = expression(scope, + CompletionKind.SINGLE_NAME_REFERENCE, + KeywordSetKey.EXPRESSION); + retVal.acceptElement(requestor, astFactory + .getReferenceManager()); + endExpression(retVal); + } + consume(IToken.tSEMI); + cleanupLastToken(); + return; + case IToken.t_goto : + consume(); + consume(IToken.tIDENTIFIER); + consume(IToken.tSEMI); + cleanupLastToken(); + return; + case IToken.t_try : + consume(); + compoundStatement(scope, true); + catchHandlerSequence(scope); + cleanupLastToken(); + return; + case IToken.tSEMI : + consume(); + cleanupLastToken(); + return; + default : + // can be many things: + // label - // declarationStatement - declaration(scope, null, null, KeywordSetKey.STATEMENT); - } + if (queryLookaheadCapability(2) && LT(1) == IToken.tIDENTIFIER + && LT(2) == IToken.tCOLON) { + consume(IToken.tIDENTIFIER); + consume(IToken.tCOLON); + statement(scope); + cleanupLastToken(); + return; + } + // expressionStatement + // Note: the function style cast ambiguity is handled in + // expression + // Since it only happens when we are in a statement + IToken mark = mark(); + IASTExpression expressionStatement = null; + try { + expressionStatement = expression(scope, + CompletionKind.SINGLE_NAME_REFERENCE, + KeywordSetKey.STATEMENT); + consume(IToken.tSEMI); + expressionStatement.acceptElement(requestor, astFactory + .getReferenceManager()); + endExpression(expressionStatement); + return; + } catch (BacktrackException b) { + backup(mark); + if (expressionStatement != null) + expressionStatement.freeReferences(astFactory + .getReferenceManager()); + } - } - protected void catchHandlerSequence(IASTScope scope) - throws EndOfFileException, BacktrackException { - if( LT(1) != IToken.t_catch ) - throw backtrack; // error, need at least one of these - while (LT(1) == IToken.t_catch) - { - consume(IToken.t_catch); - consume(IToken.tLPAREN); - if( LT(1) == IToken.tELLIPSIS ) - consume( IToken.tELLIPSIS ); - else - simpleDeclaration( SimpleDeclarationStrategy.TRY_VARIABLE, scope, null, CompletionKind.EXCEPTION_REFERENCE, true, KeywordSetKey.DECL_SPECIFIER_SEQUENCE ); - consume(IToken.tRPAREN); - - catchBlockCompoundStatement(scope); - } - } - - - protected abstract void catchBlockCompoundStatement(IASTScope scope) throws BacktrackException, EndOfFileException; - - protected void singleStatementScope(IASTScope scope) throws EndOfFileException, BacktrackException - { - IASTCodeScope newScope; - try - { - newScope = astFactory.createNewCodeBlock(scope); - } - catch (Exception e) - { - logException( "singleStatementScope:createNewCodeBlock", e ); //$NON-NLS-1$ - throw backtrack; - } - newScope.enterScope( requestor, astFactory.getReferenceManager() ); - try - { - statement( newScope ); - } - finally - { - newScope.exitScope( requestor, astFactory.getReferenceManager() ); - } - } + // declarationStatement + declaration(scope, null, null, KeywordSetKey.STATEMENT); + } - /** - * @throws BacktrackException - */ - protected void condition( IASTScope scope ) throws BacktrackException, EndOfFileException - { - IASTExpression someExpression = expression( scope, CompletionKind.SINGLE_NAME_REFERENCE, KeywordSetKey.EXPRESSION ); - someExpression.acceptElement(requestor, astFactory.getReferenceManager()); - - endExpression(someExpression); - } - - /** - * @throws BacktrackException - */ - protected void forInitStatement( IASTScope scope ) throws BacktrackException, EndOfFileException - { - IToken mark = mark(); - try - { - IASTExpression e = expression( scope, CompletionKind.SINGLE_NAME_REFERENCE, KeywordSetKey.DECLARATION ); - consume( IToken.tSEMI ); + } + protected void catchHandlerSequence(IASTScope scope) + throws EndOfFileException, BacktrackException { + if (LT(1) != IToken.t_catch) + throwBacktrack(LA(1).getOffset()); // error, need at least one of these + while (LT(1) == IToken.t_catch) { + consume(IToken.t_catch); + consume(IToken.tLPAREN); + if (LT(1) == IToken.tELLIPSIS) + consume(IToken.tELLIPSIS); + else + simpleDeclaration(SimpleDeclarationStrategy.TRY_VARIABLE, + scope, null, CompletionKind.EXCEPTION_REFERENCE, true, + KeywordSetKey.DECL_SPECIFIER_SEQUENCE); + consume(IToken.tRPAREN); + + catchBlockCompoundStatement(scope); + } + } + + protected abstract void catchBlockCompoundStatement(IASTScope scope) + throws BacktrackException, EndOfFileException; + + protected void singleStatementScope(IASTScope scope) + throws EndOfFileException, BacktrackException { + IASTCodeScope newScope; + try { + newScope = astFactory.createNewCodeBlock(scope); + } catch (Exception e) { + logException("singleStatementScope:createNewCodeBlock", e); //$NON-NLS-1$ + throwBacktrack(LA(1).getOffset()); + return; + } + newScope.enterScope(requestor, astFactory.getReferenceManager()); + try { + statement(newScope); + } finally { + newScope.exitScope(requestor, astFactory.getReferenceManager()); + } + } + + /** + * @throws BacktrackException + */ + protected void condition(IASTScope scope) throws BacktrackException, + EndOfFileException { + IASTExpression someExpression = expression(scope, + CompletionKind.SINGLE_NAME_REFERENCE, KeywordSetKey.EXPRESSION); + someExpression.acceptElement(requestor, astFactory + .getReferenceManager()); + + endExpression(someExpression); + } + + /** + * @throws BacktrackException + */ + protected void forInitStatement(IASTScope scope) throws BacktrackException, + EndOfFileException { + IToken mark = mark(); + try { + IASTExpression e = expression(scope, + CompletionKind.SINGLE_NAME_REFERENCE, + KeywordSetKey.DECLARATION); + consume(IToken.tSEMI); e.acceptElement(requestor, astFactory.getReferenceManager()); - - - } - catch( BacktrackException bt ) - { - backup( mark ); - try - { - simpleDeclarationStrategyUnion(scope,null, null,null); - } - catch( BacktrackException b ) - { - failParse(); - throw b; - } - } - - } - /** - * @throws BacktrackException - */ - protected void compoundStatement( IASTScope scope, boolean createNewScope ) throws EndOfFileException, BacktrackException - { - consume(IToken.tLBRACE); - + + } catch (BacktrackException bt) { + backup(mark); + try { + simpleDeclarationStrategyUnion(scope, null, null, null); + } catch (BacktrackException b) { + failParse(b); + throwBacktrack(b); + } + } + + } + /** + * @throws BacktrackException + */ + protected void compoundStatement(IASTScope scope, boolean createNewScope) + throws EndOfFileException, BacktrackException { + int startingOffset = consume(IToken.tLBRACE).getOffset(); + IASTCodeScope newScope = null; - if( createNewScope ) - { - try - { - newScope = astFactory.createNewCodeBlock(scope); - } - catch (Exception e) - { - logException( "compoundStatement:createNewCodeBlock", e ); //$NON-NLS-1$ - throw backtrack; - } - newScope.enterScope( requestor, astFactory.getReferenceManager() ); - } - - setCompletionValues( - (createNewScope ? newScope : scope ), - CompletionKind.SINGLE_NAME_REFERENCE, - KeywordSetKey.STATEMENT ); - - while (LT(1) != IToken.tRBRACE) - { - int checkToken = LA(1).hashCode(); - try - { - statement((IASTCodeScope) (createNewScope ? newScope : scope) ); - } - catch( BacktrackException b ) - { - failParse(); - if( LA(1).hashCode() == checkToken ) - errorHandling(); - } - setCompletionValues(((createNewScope ? newScope : scope )), CompletionKind.SINGLE_NAME_REFERENCE, - KeywordSetKey.STATEMENT ); - } - - consume(IToken.tRBRACE); - - if( createNewScope ) - newScope.exitScope( requestor, astFactory.getReferenceManager() ); - } - - protected IASTCompilationUnit compilationUnit; + if (createNewScope) { + try { + newScope = astFactory.createNewCodeBlock(scope); + } catch (Exception e) { + logException("compoundStatement:createNewCodeBlock", e); //$NON-NLS-1$ + throwBacktrack(startingOffset); + } + newScope.enterScope(requestor, astFactory.getReferenceManager()); + } + + setCompletionValues((createNewScope ? newScope : scope), + CompletionKind.SINGLE_NAME_REFERENCE, KeywordSetKey.STATEMENT); + + while (LT(1) != IToken.tRBRACE) { + int checkToken = LA(1).hashCode(); + try { + statement((IASTCodeScope) (createNewScope ? newScope : scope)); + } catch (BacktrackException b) { + failParse(b); + if (LA(1).hashCode() == checkToken) + errorHandling(); + } + setCompletionValues(((createNewScope ? newScope : scope)), + CompletionKind.SINGLE_NAME_REFERENCE, + KeywordSetKey.STATEMENT); + } + + consume(IToken.tRBRACE); + + if (createNewScope) + newScope.exitScope(requestor, astFactory.getReferenceManager()); + } + + protected IASTCompilationUnit compilationUnit; protected IToken simpleDeclarationMark; - - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser.IParser#getLanguage() - */ - public ParserLanguage getLanguage() - { - return language; - } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser.IParser#setLanguage(Language) - */ - public void setLanguage( ParserLanguage l ) - { - language = l; - } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser.IParser#getLastErrorOffset() - */ - public int getLastErrorOffset() - { - return firstErrorOffset; - } - - protected void setCompletionToken( IToken token ) - { - // do nothing! - } - - protected IToken getCompletionToken() - { - return null; - } - - /* (non-Javadoc) + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser.IParser#getLanguage() + */ + public ParserLanguage getLanguage() { + return language; + } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser.IParser#setLanguage(Language) + */ + public void setLanguage(ParserLanguage l) { + language = l; + } + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser.IParser#getLastErrorOffset() + */ + public int getLastErrorOffset() { + return firstErrorOffset; + } + + protected void setCompletionToken(IToken token) { + // do nothing! + } + + protected IToken getCompletionToken() { + return null; + } + + /* + * (non-Javadoc) + * * @see org.eclipse.cdt.core.parser.IParser#parse(int, int) */ public ISelectionParseResult parse(int startingOffset, int endingOffset) - throws ParseError { - throw new ParseError( ParseError.ParseErrorKind.METHOD_NOT_IMPLEMENTED ); + throws ParseError { + throw new ParseError(ParseError.ParseErrorKind.METHOD_NOT_IMPLEMENTED); } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see org.eclipse.cdt.core.parser.IParser#parse(int) */ public IASTCompletionNode parse(int offset) throws ParseError { - throw new ParseError( ParseError.ParseErrorKind.METHOD_NOT_IMPLEMENTED ); + throw new ParseError(ParseError.ParseErrorKind.METHOD_NOT_IMPLEMENTED); } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser.ExpressionParser#setupASTFactory(org.eclipse.cdt.core.parser.IScanner, org.eclipse.cdt.core.parser.ParserLanguage) + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser.ExpressionParser#setupASTFactory(org.eclipse.cdt.core.parser.IScanner, + * org.eclipse.cdt.core.parser.ParserLanguage) */ protected void setupASTFactory(IScanner scanner, ParserLanguage language) { // do nothing as of yet // subclasses will need to implement this method } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see org.eclipse.cdt.internal.core.parser.ExpressionParser#parserTimeout() */ protected final boolean parserTimeout() { return requestor.parserTimeout(); } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see org.eclipse.cdt.internal.core.parser.ExpressionParser#getCompliationUnit() */ protected IASTNode getCompliationUnit() { return compilationUnit; } - - protected void endDeclaration( IASTDeclaration declaration ) throws EndOfFileException - { + + protected void endDeclaration(IASTDeclaration declaration) + throws EndOfFileException { cleanupLastToken(); - if( declaration instanceof IASTOffsetableNamedElement ) - handleOffsetableNamedElement( (IASTOffsetableNamedElement) declaration ); + if (declaration instanceof IASTOffsetableNamedElement) + handleOffsetableNamedElement((IASTOffsetableNamedElement) declaration); } - - protected void endEnumerator( IASTEnumerator enumerator ) throws EndOfFileException - { + + protected void endEnumerator(IASTEnumerator enumerator) + throws EndOfFileException { cleanupLastToken(); handleOffsetableNamedElement(enumerator); } - + /** - * + * */ protected void cleanupLastToken() { - if( lastToken != null ) - lastToken.setNext( null ); + if (lastToken != null) + lastToken.setNext(null); simpleDeclarationMark = null; } - - protected void endExpression( IASTExpression expression ) throws EndOfFileException - { + protected void endExpression(IASTExpression expression) + throws EndOfFileException { cleanupLastToken(); } - - protected void handleClassSpecifier( IASTClassSpecifier classSpecifier ) throws EndOfFileException - { - cleanupLastToken(); - handleOffsetableNamedElement( classSpecifier ); - } + protected void handleClassSpecifier(IASTClassSpecifier classSpecifier) + throws EndOfFileException { + cleanupLastToken(); + handleOffsetableNamedElement(classSpecifier); + } protected void handleEnumeration(IASTEnumerationSpecifier enumeration) throws EndOfFileException { cleanupLastToken(); handleOffsetableNamedElement( enumeration ); - } - - /** + } /** * @param expression */ - protected void handleOffsetableNamedElement(IASTOffsetableNamedElement node ) { + protected void handleOffsetableNamedElement(IASTOffsetableNamedElement node) { } - -} + +} \ No newline at end of file