diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ITokenDuple.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ITokenDuple.java index 286ef9c9c0c..e8b696755b6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ITokenDuple.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ITokenDuple.java @@ -13,10 +13,6 @@ package org.eclipse.cdt.core.parser; import java.util.Iterator; import java.util.List; -import org.eclipse.cdt.core.parser.ast.IASTFactory; -import org.eclipse.cdt.core.parser.ast.IASTNode; -import org.eclipse.cdt.core.parser.ast.IASTScope; - /** * @author jcamelon @@ -48,7 +44,6 @@ public interface ITokenDuple { public int findLastTokenType( int type ); - public IASTNode lookup( IASTFactory factory, IASTScope scope ); public int getStartOffset(); public int getEndOffset(); public int getLineNumber(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTFactory.java index 9b8d0282ed3..d441b5ac0db 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTFactory.java @@ -239,7 +239,7 @@ public interface IASTFactory */ public void signalEndOfClassSpecifier(IASTClassSpecifier astClassSpecifier); - public IASTNode lookupSymbolInContext( IASTScope scope, ITokenDuple duple ) throws ASTNotImplementedException; + public IASTNode lookupSymbolInContext( IASTScope scope, ITokenDuple duple, IASTNode reference ) throws ASTNotImplementedException; /** * @param log diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ContextualParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ContextualParser.java index 808de80ef2b..b79a6bf6383 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ContextualParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ContextualParser.java @@ -155,7 +155,7 @@ public class ContextualParser extends CompleteParser { setCompletionKeywords(key); ITokenDuple duple = new TokenDuple( first, last ); try { - setCompletionContext( astFactory.lookupSymbolInContext( scope, duple ) ); + setCompletionContext( astFactory.lookupSymbolInContext( scope, duple, null ) ); } catch (ASTNotImplementedException e) { } setCompletionFunctionName(); 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 115065077f5..a879b4ae9a0 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 @@ -2840,10 +2840,12 @@ public abstract class Parser extends ExpressionParser implements IParser 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(); @@ -2853,19 +2855,23 @@ public abstract class Parser extends ExpressionParser implements IParser retVal.acceptElement(requestor); } 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: @@ -2876,6 +2882,7 @@ public abstract class Parser extends ExpressionParser implements IParser consume(IToken.tIDENTIFIER); consume(IToken.tCOLON); statement(scope); + cleanupLastToken(); return; } // expressionStatement @@ -2887,6 +2894,7 @@ public abstract class Parser extends ExpressionParser implements IParser IASTExpression expressionStatement = expression(scope, CompletionKind.SINGLE_NAME_REFERENCE, Key.STATEMENT); consume(IToken.tSEMI); expressionStatement.acceptElement( requestor ); + endExpressionStatement(expressionStatement); return; } catch (BacktrackException b) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/SelectionParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/SelectionParser.java index 47113b201a1..b46074992fc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/SelectionParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/SelectionParser.java @@ -20,8 +20,12 @@ import org.eclipse.cdt.core.parser.IToken; import org.eclipse.cdt.core.parser.ITokenDuple; import org.eclipse.cdt.core.parser.ParseError; import org.eclipse.cdt.core.parser.ParserLanguage; +import org.eclipse.cdt.core.parser.ast.ASTNotImplementedException; import org.eclipse.cdt.core.parser.ast.IASTCompletionNode; +import org.eclipse.cdt.core.parser.ast.IASTDeclaration; +import org.eclipse.cdt.core.parser.ast.IASTExpression; import org.eclipse.cdt.core.parser.ast.IASTNode; +import org.eclipse.cdt.core.parser.ast.IASTOffsetableNamedElement; import org.eclipse.cdt.core.parser.ast.IASTScope; import org.eclipse.cdt.core.parser.extension.IParserExtension; import org.eclipse.cdt.internal.core.parser.token.OffsetDuple; @@ -40,6 +44,7 @@ public class SelectionParser extends ContextualParser { private IASTNode ourContext = null; private ITokenDuple greaterContextDuple = null; private boolean pastPointOfSelection = false; + private IASTNode contextNode = null; /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.parser.Parser#handleNewToken(org.eclipse.cdt.core.parser.IToken) @@ -58,7 +63,7 @@ public class SelectionParser extends ContextualParser { TraceUtil.outputTrace(log, "Offset Ceiling Hit w/token \"", null, value.getImage(), "\"", null ); //$NON-NLS-1$ //$NON-NLS-2$ lastTokenOfDuple = value; } - if( lastTokenOfDuple != null && lastTokenOfDuple.getEndOffset() >= offsetRange.getCeilingOffset() ) + if( tokenDupleCompleted() ) { if ( ourScope == null ) ourScope = getCompletionScope(); @@ -73,6 +78,16 @@ public class SelectionParser extends ContextualParser { + /** + * @return + */ + protected boolean tokenDupleCompleted() { + return lastTokenOfDuple != null && lastTokenOfDuple.getEndOffset() >= offsetRange.getCeilingOffset(); + } + + + + /** * @param scanner * @param callback @@ -121,30 +136,55 @@ public class SelectionParser extends ContextualParser { // reconcile the name to look up first if( ! duple.equals( greaterContextDuple )) { - // 3 cases - + // 3 cases // duple is prefix of greaterContextDuple - if( duple.getFirstToken().equals( greaterContextDuple.getFirstToken() )) - { - // => do not use greaterContextDuple - finalDuple = duple; - } - // duple is suffix of greaterContextDuple - else if( duple.getLastToken().equals( greaterContextDuple.getLastToken() )) - { - // => use greaterContextDuple - finalDuple = greaterContextDuple; - } + // or duple is suffix of greaterContextDuple // duple is a sub-duple of greaterContextDuple + if( duple.getFirstToken().equals( greaterContextDuple.getFirstToken() )) + finalDuple = duple; // => do not use greaterContextDuple + else if( duple.getLastToken().equals( greaterContextDuple.getLastToken() )) + finalDuple = greaterContextDuple; // => use greaterContextDuple else - { - // => throw ParseError throw new ParseError( ParseError.ParseErrorKind.OFFSET_RANGE_NOT_NAME ); - } } else finalDuple = greaterContextDuple; - return finalDuple.lookup( astFactory, ourScope ); + + + return lookupNode(finalDuple); + } + + + + + /** + * @param finalDuple + * @return + */ + protected IASTNode lookupNode(ITokenDuple finalDuple) { + if( contextNode == null ) return null; + if( contextNode instanceof IASTDeclaration ) + { + if( contextNode instanceof IASTOffsetableNamedElement ) + { + if( ((IASTOffsetableNamedElement)contextNode).getName().equals( finalDuple.toString() ) ) + return contextNode; + } + try { + return astFactory.lookupSymbolInContext( ourScope, finalDuple, null ); + } catch (ASTNotImplementedException e) { + return null; + } + } + else if( contextNode instanceof IASTExpression ) + { + try { + return astFactory.lookupSymbolInContext( ourScope, finalDuple, contextNode ); + } catch (ASTNotImplementedException e) { + return null; + } + } + return null; } @@ -189,4 +229,33 @@ public class SelectionParser extends ContextualParser { greaterContextDuple = tokenDuple; } } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.Parser#endDeclaration(org.eclipse.cdt.core.parser.ast.IASTDeclaration) + */ + protected void endDeclaration(IASTDeclaration declaration) + throws EndOfFileException { + if( ! tokenDupleCompleted() ) + super.endDeclaration(declaration); + else + { + contextNode = declaration; + throw new EndOfFileException(); + } + } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.Parser#endExpressionStatement(org.eclipse.cdt.core.parser.ast.IASTExpression) + */ + protected void endExpressionStatement(IASTExpression expression) + throws EndOfFileException { + if( ! tokenDupleCompleted() ) + super.endExpressionStatement(expression); + else + { + contextNode = expression; + throw new EndOfFileException(); + } + + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTExpression.java index a89c0ba53ab..255465111ad 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTExpression.java @@ -20,6 +20,7 @@ import org.eclipse.cdt.core.parser.ast.ASTNotImplementedException; import org.eclipse.cdt.core.parser.ast.IASTExpression; import org.eclipse.cdt.core.parser.ast.IASTReference; import org.eclipse.cdt.core.parser.ast.IASTTypeId; +import org.eclipse.cdt.core.parser.ast.IASTNode.LookupError; import org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol; import org.eclipse.cdt.internal.core.parser.pst.TypeInfo; @@ -310,7 +311,6 @@ public class ASTExpression extends ASTNode implements IASTExpression } return stringRepresentation; } - public IContainerSymbol getLookupQualificationSymbol() throws LookupError { ExpressionResult result = getResultType(); TypeInfo type = (result != null ) ? getResultType().getResult() : null; @@ -325,5 +325,36 @@ public class ASTExpression extends ASTNode implements IASTExpression } return null; + } /** + * @param duple + * @return + */ + public ASTExpression findOwnerExpressionForIDExpression(ITokenDuple duple) { + if( isIDExpressionForDuple( lhs, duple ) || isIDExpressionForDuple(rhs, duple) || isIDExpressionForDuple(thirdExpression, duple)) + return this; + ASTExpression result = recursiveFindExpressionForDuple(lhs, duple); + if( result != null ) return result; + result = recursiveFindExpressionForDuple(rhs, duple); + if( result != null ) return result; + result = recursiveFindExpressionForDuple(thirdExpression, duple); + return result; + } + + /** + * @param duple + * @return + */ + private ASTExpression recursiveFindExpressionForDuple(IASTExpression expression, ITokenDuple duple) { + return ((ASTExpression)expression).findOwnerExpressionForIDExpression(duple); + } + + protected boolean isIDExpressionForDuple( IASTExpression expression, ITokenDuple duple ) + { + if( expression == null ) return false; + if( expression.getExpressionKind() == IASTExpression.Kind.ID_EXPRESSION && + expression instanceof ASTExpression && + ((ASTExpression)expression).getIdExpressionTokenDuple().equals( duple ) ) + return true; + return false; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java index d965dafe089..d160cb3455c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java @@ -3294,11 +3294,47 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto /* (non-Javadoc) * @see org.eclipse.cdt.core.parser.ast.IASTFactory#lookupSymbolInContext(org.eclipse.cdt.core.parser.ast.IASTScope, org.eclipse.cdt.core.parser.ITokenDuple) */ - public IASTNode lookupSymbolInContext(IASTScope scope, ITokenDuple duple) throws ASTNotImplementedException { + public IASTNode lookupSymbolInContext(IASTScope scope, ITokenDuple duple, IASTNode reference) throws ASTNotImplementedException { ISymbol s = null; - try { - s = lookupQualifiedName( scopeToSymbol( scope ), duple, new ArrayList(), false ); - } catch (ASTSemanticException e) { + if( reference == null ) { + try { + s = lookupQualifiedName( scopeToSymbol( scope ), duple, new ArrayList(), false ); + } catch (ASTSemanticException e) { + } + } + else + { + if( reference instanceof ASTExpression ) + { + ASTExpression expression = (ASTExpression) reference; + if( expression.getExpressionKind() == IASTExpression.Kind.ID_EXPRESSION ) + { + try { + s = lookupQualifiedName( scopeToSymbol( scope ), duple, new ArrayList(), false ); + } catch (ASTSemanticException e1) { + } + } + else + { + ASTExpression ownerExpression = expression.findOwnerExpressionForIDExpression( duple ); + if( ownerExpression == null ) return null; + if( ownerExpression.getExpressionKind().isPostfixMemberReference() ) + { + try { + s = lookupQualifiedName( getSearchScope(ownerExpression.getExpressionKind(), ownerExpression.getLHSExpression(), scopeToSymbol(scope)), duple, new ArrayList(), false ); + } catch (ASTSemanticException e) { + return null; + } + } + else + { + try { + s = lookupQualifiedName( scopeToSymbol( scope ), duple, new ArrayList(), false ); + } catch (ASTSemanticException e1) { + } + } + } + } } if ( s == null ) return null; return s.getASTExtension().getPrimaryDeclaration(); @@ -3314,7 +3350,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto if( expression instanceof ASTExpression) { try { - return lookupSymbolInContext(scope, ((ASTExpression)expression).getIdExpressionTokenDuple()); + return lookupSymbolInContext(scope, ((ASTExpression)expression).getIdExpressionTokenDuple(), null); } catch (ASTNotImplementedException e) { // assert false : e; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/expression/ExpressionParseASTFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/expression/ExpressionParseASTFactory.java index 9a7b2a66d8c..5b738907b8a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/expression/ExpressionParseASTFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/expression/ExpressionParseASTFactory.java @@ -878,7 +878,7 @@ public class ExpressionParseASTFactory extends BaseASTFactory implements IASTFac * @see org.eclipse.cdt.core.parser.ast.IASTFactory#lookupSymbolInContext(org.eclipse.cdt.core.parser.ast.IASTScope, * org.eclipse.cdt.core.parser.ITokenDuple) */ - public IASTNode lookupSymbolInContext(IASTScope scope, ITokenDuple duple) + public IASTNode lookupSymbolInContext(IASTScope scope, ITokenDuple duple, IASTNode reference) throws ASTNotImplementedException { return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/quick/QuickParseASTFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/quick/QuickParseASTFactory.java index fbbd0ed3d4f..3083585743e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/quick/QuickParseASTFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/quick/QuickParseASTFactory.java @@ -348,7 +348,7 @@ public class QuickParseASTFactory extends BaseASTFactory implements IASTFactory /* (non-Javadoc) * @see org.eclipse.cdt.core.parser.ast.IASTFactory#lookupSymbolInContext(org.eclipse.cdt.core.parser.ast.IASTScope, org.eclipse.cdt.core.parser.ITokenDuple) */ - public IASTNode lookupSymbolInContext(IASTScope scope, ITokenDuple duple) throws ASTNotImplementedException { + public IASTNode lookupSymbolInContext(IASTScope scope, ITokenDuple duple, IASTNode reference) throws ASTNotImplementedException { throw new ASTNotImplementedException(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/TokenDuple.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/TokenDuple.java index a2c491ea7da..27a4b81d908 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/TokenDuple.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/TokenDuple.java @@ -18,10 +18,6 @@ import java.util.NoSuchElementException; import org.eclipse.cdt.core.parser.IToken; import org.eclipse.cdt.core.parser.ITokenDuple; -import org.eclipse.cdt.core.parser.ast.ASTNotImplementedException; -import org.eclipse.cdt.core.parser.ast.IASTFactory; -import org.eclipse.cdt.core.parser.ast.IASTNode; -import org.eclipse.cdt.core.parser.ast.IASTScope; /** * @author jcamelon @@ -362,19 +358,6 @@ public class TokenDuple implements ITokenDuple { return lastFound; } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.parser.ITokenDuple#lookup(org.eclipse.cdt.core.parser.ast.IASTFactory) - */ - public IASTNode lookup(IASTFactory factory, IASTScope scope) { - // check syntax of the node - - try { - return factory.lookupSymbolInContext(scope, this ); - } catch (ASTNotImplementedException e) { - return null; - } - } /* (non-Javadoc) * @see org.eclipse.cdt.core.parser.ITokenDuple#getEndOffset()