From 7a2c6de5fb3f720d4ccf6d80c100a157056f2b77 Mon Sep 17 00:00:00 2001 From: John Camelon Date: Tue, 27 Apr 2004 21:56:53 +0000 Subject: [PATCH] Updated Selection Search to use the parser exclusively for Open Declaration actions.
Fixed OpenDeclarationAction to open external files again. --- .../parser/tests/CompleteParseBaseTest.java | 16 ++ .../core/parser/tests/SelectionParseTest.java | 4 +- .../cdt/core/parser/IFilenameProvider.java | 2 + .../org/eclipse/cdt/core/parser/IParser.java | 10 +- .../internal/core/parser/CompleteParser.java | 3 +- .../core/parser/CompletionParser.java | 3 +- .../core/parser/ExpressionParser.java | 12 ++ .../cdt/internal/core/parser/Parser.java | 12 +- .../cdt/internal/core/parser/QuickParser.java | 3 +- .../internal/core/parser/SelectionParser.java | 56 +++++- .../core/parser/StructuralParser.java | 3 +- .../core/parser/ast/ASTInclusion.java | 16 ++ .../internal/core/parser/ast/ASTMacro.java | 16 ++ .../parser/ast/complete/ASTExpression.java | 1 + .../ast/complete/CompleteParseASTFactory.java | 2 + .../core/parser/scanner/ContextStack.java | 60 +++++- .../core/parser/scanner/IScannerContext.java | 2 + .../parser/scanner/LimitedScannerContext.java | 4 +- .../internal/core/parser/scanner/Scanner.java | 22 ++- .../core/parser/scanner/ScannerContext.java | 15 +- .../eclipse/cdt/core/parser/ParserUtil.java | 29 ++- .../ui/search/actions/FindAction.java | 12 +- .../actions/OpenDeclarationsAction.java | 181 ++++++++++++++---- 23 files changed, 397 insertions(+), 87 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseBaseTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseBaseTest.java index 3747507b0b0..d91e8b9c65a 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseBaseTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseBaseTest.java @@ -129,6 +129,22 @@ public class CompleteParseBaseTest extends TestCase return null; } + /* (non-Javadoc) + * @see org.eclipse.cdt.core.parser.ast.IASTNode#getFileIndex() + */ + public int getFileIndex() { + // TODO Auto-generated method stub + return 0; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.parser.ast.IASTNode#setFileIndex(int) + */ + public void setFileIndex(int index) { + // TODO Auto-generated method stub + + } + } public static class CodeScope extends Scope implements IASTCodeScope diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/SelectionParseTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/SelectionParseTest.java index 5b146802894..7fa800b961d 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/SelectionParseTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/SelectionParseTest.java @@ -53,7 +53,9 @@ public class SelectionParseTest extends CompleteParseBaseTest { ParserLanguage.CPP, ParserUtil.getParserLogService()); - return parser.parse( offset1, offset2 ); + IParser.ISelectionParseResult result =parser.parse( offset1, offset2 ); + if( result == null ) return null; + return (IASTNode) result.getOffsetableNamedElement(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IFilenameProvider.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IFilenameProvider.java index f94777eb88b..693ee3501e8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IFilenameProvider.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IFilenameProvider.java @@ -16,5 +16,7 @@ package org.eclipse.cdt.core.parser; public interface IFilenameProvider { public char [] getCurrentFilename(); + public int getCurrentFileIndex(); + public String getFilenameForIndex( int index ); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IParser.java index 69eb18d632e..53593c5ccfc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IParser.java @@ -11,7 +11,7 @@ package org.eclipse.cdt.core.parser; import org.eclipse.cdt.core.parser.ast.IASTCompletionNode; -import org.eclipse.cdt.core.parser.ast.IASTNode; +import org.eclipse.cdt.core.parser.ast.IASTOffsetableNamedElement; /** @@ -36,13 +36,19 @@ public interface IParser { */ public IASTCompletionNode parse( int offset) throws ParseError; + + public static interface ISelectionParseResult + { + public IASTOffsetableNamedElement getOffsetableNamedElement(); + public String getFilename(); + } /** * * @param startingOffset * @param endingOffset * @return */ - public IASTNode parse( int startingOffset, int endingOffset ) throws ParseError; + public ISelectionParseResult parse( int startingOffset, int endingOffset ) throws ParseError; /** * If an error was encountered, give us the offset of the token that caused the error. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/CompleteParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/CompleteParser.java index 82bb2a68d60..812dad330f8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/CompleteParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/CompleteParser.java @@ -20,7 +20,6 @@ import org.eclipse.cdt.core.parser.ParserFactory; import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ParserMode; import org.eclipse.cdt.core.parser.ast.IASTCompletionNode; -import org.eclipse.cdt.core.parser.ast.IASTNode; import org.eclipse.cdt.core.parser.ast.IASTScope; import org.eclipse.cdt.core.parser.extension.IParserExtension; @@ -60,7 +59,7 @@ public class CompleteParser extends Parser { /* (non-Javadoc) * @see org.eclipse.cdt.core.parser.IParser#parse(int, int) */ - public IASTNode parse(int startingOffset, int endingOffset) throws ParseError { + public ISelectionParseResult parse(int startingOffset, int endingOffset) throws ParseError { throw new ParseError( ParseError.ParseErrorKind.METHOD_NOT_IMPLEMENTED ); } 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 24c67f913ce..6715c89578e 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 @@ -29,7 +29,6 @@ import org.eclipse.cdt.core.parser.ParserMode; import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier; import org.eclipse.cdt.core.parser.ast.IASTCodeScope; import org.eclipse.cdt.core.parser.ast.IASTCompletionNode; -import org.eclipse.cdt.core.parser.ast.IASTNode; import org.eclipse.cdt.core.parser.ast.IASTScope; import org.eclipse.cdt.core.parser.ast.IASTCompletionNode.CompletionKind; import org.eclipse.cdt.core.parser.extension.IParserExtension; @@ -149,7 +148,7 @@ public class CompletionParser extends ContextualParser implements IParser { } } - public IASTNode parse(int startingOffset, int endingOffset) { + public ISelectionParseResult parse(int startingOffset, int endingOffset) { throw new ParseError( ParseError.ParseErrorKind.METHOD_NOT_IMPLEMENTED ); } 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 f80ac7e9509..269d8fab9e8 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 @@ -2916,4 +2916,16 @@ public class ExpressionParser implements IExpressionParser, IParserData { IToken first = consume(IToken.tIDENTIFIER); // throws backtrack if its not that return first; } + /* (non-Javadoc) + * @see org.eclipse.cdt.core.parser.IFilenameProvider#getCurrentFileIndex() + */ + public int getCurrentFileIndex() { + return scanner.getCurrentFileIndex(); + } + /* (non-Javadoc) + * @see org.eclipse.cdt.core.parser.IFilenameProvider#getFilenameForIndex(int) + */ + public String getFilenameForIndex(int index) { + return scanner.getFilenameForIndex(index); + } } 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 a879b4ae9a0..078a786b55f 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 @@ -43,6 +43,7 @@ import org.eclipse.cdt.core.parser.ast.IASTNamespaceAlias; import org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition; import org.eclipse.cdt.core.parser.ast.IASTNode; import org.eclipse.cdt.core.parser.ast.IASTOffsetableElement; +import org.eclipse.cdt.core.parser.ast.IASTOffsetableNamedElement; import org.eclipse.cdt.core.parser.ast.IASTScope; import org.eclipse.cdt.core.parser.ast.IASTSimpleTypeSpecifier; import org.eclipse.cdt.core.parser.ast.IASTTemplate; @@ -3076,7 +3077,7 @@ public abstract class Parser extends ExpressionParser implements IParser /* (non-Javadoc) * @see org.eclipse.cdt.core.parser.IParser#parse(int, int) */ - public IASTNode parse(int startingOffset, int endingOffset) + public ISelectionParseResult parse(int startingOffset, int endingOffset) throws ParseError { throw new ParseError( ParseError.ParseErrorKind.METHOD_NOT_IMPLEMENTED ); } @@ -3111,6 +3112,8 @@ public abstract class Parser extends ExpressionParser implements IParser protected void endDeclaration( IASTDeclaration declaration ) throws EndOfFileException { cleanupLastToken(); + if( declaration instanceof IASTOffsetableNamedElement ) + handleNode( (IASTOffsetableNamedElement) declaration ); } /** @@ -3126,4 +3129,11 @@ public abstract class Parser extends ExpressionParser implements IParser { cleanupLastToken(); } + + + /** + * @param expression + */ + protected void handleNode(IASTOffsetableNamedElement node ) { + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/QuickParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/QuickParser.java index 62327f691d2..ae153feaf15 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/QuickParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/QuickParser.java @@ -21,7 +21,6 @@ import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ParserMode; import org.eclipse.cdt.core.parser.ParseError.ParseErrorKind; import org.eclipse.cdt.core.parser.ast.IASTCompletionNode; -import org.eclipse.cdt.core.parser.ast.IASTNode; import org.eclipse.cdt.core.parser.ast.IASTScope; import org.eclipse.cdt.core.parser.extension.IParserExtension; @@ -61,7 +60,7 @@ public class QuickParser extends Parser { /* (non-Javadoc) * @see org.eclipse.cdt.core.parser.IParser#parse(int, int) */ - public IASTNode parse(int startingOffset, int endingOffset) throws ParseError { + public ISelectionParseResult parse(int startingOffset, int endingOffset) throws ParseError { throw new ParseError( ParseErrorKind.METHOD_NOT_IMPLEMENTED ); } 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 b46074992fc..535a3b1b613 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 @@ -10,7 +10,9 @@ ***********************************************************************/ package org.eclipse.cdt.internal.core.parser; +import java.util.Hashtable; import java.util.Iterator; +import java.util.Map; import org.eclipse.cdt.core.parser.EndOfFileException; import org.eclipse.cdt.core.parser.IParserLogService; @@ -45,6 +47,8 @@ public class SelectionParser extends ContextualParser { private ITokenDuple greaterContextDuple = null; private boolean pastPointOfSelection = false; private IASTNode contextNode = null; + private static final int DEFAULT_MAP_SIZE = 512; + private static final float DEFAULT_FLOAT_SIZE = 0.75f; /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.parser.Parser#handleNewToken(org.eclipse.cdt.core.parser.IToken) @@ -102,7 +106,7 @@ public class SelectionParser extends ContextualParser { /* (non-Javadoc) * @see org.eclipse.cdt.core.parser.IParser#parse(int, int) */ - public IASTNode parse(int startingOffset, int endingOffset) { + public ISelectionParseResult parse(int startingOffset, int endingOffset) { offsetRange = new OffsetDuple( startingOffset, endingOffset ); translationUnit(); return reconcileTokenDuple(); @@ -111,7 +115,7 @@ public class SelectionParser extends ContextualParser { /** * */ - protected IASTNode reconcileTokenDuple() throws ParseError { + protected ISelectionParseResult reconcileTokenDuple() throws ParseError { if( firstTokenOfDuple == null || lastTokenOfDuple == null ) throw new ParseError( ParseError.ParseErrorKind.OFFSET_RANGE_NOT_NAME ); @@ -130,7 +134,7 @@ public class SelectionParser extends ContextualParser { * @param duple * @return */ - protected IASTNode provideSelectionNode(ITokenDuple duple) { + protected ISelectionParseResult provideSelectionNode(ITokenDuple duple) { ITokenDuple finalDuple = null; // reconcile the name to look up first @@ -150,8 +154,15 @@ public class SelectionParser extends ContextualParser { else finalDuple = greaterContextDuple; + IASTNode node = lookupNode(finalDuple); + if( node == null ) return null; + if( !(node instanceof IASTOffsetableNamedElement )) return null; + int indexValue = -1; + Object index = nodeTable.get( node ); + if( index instanceof Integer ) + indexValue = ((Integer)index).intValue(); - return lookupNode(finalDuple); + return new SelectionParseResult( (IASTOffsetableNamedElement) node, getFilenameForIndex(indexValue) ); } @@ -258,4 +269,41 @@ public class SelectionParser extends ContextualParser { } } + + protected Map nodeTable = new Hashtable( DEFAULT_MAP_SIZE, DEFAULT_FLOAT_SIZE ); + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.Parser#handleNode(org.eclipse.cdt.core.parser.ast.IASTNode) + */ + protected void handleNode(IASTOffsetableNamedElement node) { + if( node != null ) + nodeTable.put( node, new Integer( getCurrentFileIndex()) ); + } + + public static class SelectionParseResult implements ISelectionParseResult + { + + public SelectionParseResult( IASTOffsetableNamedElement node, String fileName ) + { + this.node = node; + this.fileName = fileName; + } + + private final String fileName; + private final IASTOffsetableNamedElement node; + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.parser.IParser.ISelectionParseResult#getNode() + */ + public IASTOffsetableNamedElement getOffsetableNamedElement() { + return node; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.parser.IParser.ISelectionParseResult#getFilename() + */ + public String getFilename() { + return fileName; + } + + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/StructuralParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/StructuralParser.java index 56b8c0e6045..5406e1eecb2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/StructuralParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/StructuralParser.java @@ -22,7 +22,6 @@ import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ParserMode; import org.eclipse.cdt.core.parser.ParseError.ParseErrorKind; import org.eclipse.cdt.core.parser.ast.IASTCompletionNode; -import org.eclipse.cdt.core.parser.ast.IASTNode; import org.eclipse.cdt.core.parser.ast.IASTScope; import org.eclipse.cdt.core.parser.extension.IParserExtension; @@ -69,7 +68,7 @@ public class StructuralParser extends Parser implements IParser { /* (non-Javadoc) * @see org.eclipse.cdt.core.parser.IParser#parse(int, int) */ - public IASTNode parse(int startingOffset, int endingOffset) throws ParseError { + public ISelectionParseResult parse(int startingOffset, int endingOffset) throws ParseError { throw new ParseError( ParseErrorKind.METHOD_NOT_IMPLEMENTED ); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/ASTInclusion.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/ASTInclusion.java index 34d091c45d7..82ca93e712b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/ASTInclusion.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/ASTInclusion.java @@ -157,6 +157,7 @@ public class ASTInclusion implements IASTInclusion { } private int startingLineNumber, endingLineNumber, nameLineNumber; + /* (non-Javadoc) * @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#getStartingLine() */ @@ -175,4 +176,19 @@ public class ASTInclusion implements IASTInclusion { public int getNameLineNumber() { return nameLineNumber; } + + private int fileIndex; + /* (non-Javadoc) + * @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#getFileIndex() + */ + public int getFileIndex() { + return fileIndex; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#setFileIndex() + */ + public void setFileIndex(int index) { + fileIndex = index; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/ASTMacro.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/ASTMacro.java index ec712845788..1f9b059229e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/ASTMacro.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/ASTMacro.java @@ -186,4 +186,20 @@ public class ASTMacro implements IASTMacro { public boolean isCircular() { return innerMacro.isCircular(); } + + private int fileIndex; + /* (non-Javadoc) + * @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#getFileIndex() + */ + public int getFileIndex() { + return fileIndex; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#setFileIndex() + */ + public void setFileIndex(int index) { + fileIndex = index; + } + } 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 757d2f69f0b..99264c79ada 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 @@ -344,6 +344,7 @@ public class ASTExpression extends ASTNode implements IASTExpression * @return */ private ASTExpression recursiveFindExpressionForDuple(IASTExpression expression, ITokenDuple duple) { + if( expression == null ) return null; return ((ASTExpression)expression).findOwnerExpressionForIDExpression(duple); } 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 075d020e6f1..a1e91345055 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 @@ -2402,6 +2402,8 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto resolveLeftoverConstructorInitializerMembers( symbol, constructorChain ); ASTMethod method = new ASTMethod( symbol, parameters, returnType, exception, startOffset, startingLine, nameOffset, nameEndOffset, nameLine, ownerTemplate, references, previouslyDeclared, isConstructor, isDestructor, isPureVirtual, visibility, constructorChain, hasFunctionTryBlock, isFriend ); + if( functionDeclaration != null && isFunctionDefinition ) + attachSymbolExtension( symbol, (ASTSymbol) functionDeclaration.getASTExtension().getPrimaryDeclaration(), false ); attachSymbolExtension( symbol, method, isFunctionDefinition ); return method; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ContextStack.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ContextStack.java index e3f2f8cbc02..50bf5a6d261 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ContextStack.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ContextStack.java @@ -45,13 +45,49 @@ public class ContextStack { public int getLine() { return -1; } public int undoStackSize() { return 0; } public int popUndo() { return '\n'; } + public int getFilenameIndex() { return -1; } } private final IParserLogService log; private int current_size = 8; - + private IScannerContext [] cs = new IScannerContext[current_size]; private int cs_pos = 0; + private int currentInclusionArraySize = 16; + private int currentInclusionIndex = 0; + private String [] fileNames = new String[ currentInclusionArraySize ]; + private static final String EMPTY_STRING = ""; //$NON-NLS-1$ + + + + public final String getInclusionFilename( int index ) + { + try + { + return fileNames[ index ]; + } + catch( ArrayIndexOutOfBoundsException aioobe ) + { + return EMPTY_STRING; + } + } + + private final void addInclusionFilename( String filename ) + { + try + { + fileNames[ currentInclusionIndex++ ] = filename; + } + catch( ArrayIndexOutOfBoundsException aioobe ) + { + int newSize = currentInclusionArraySize * 2; + String newFileNames [] = new String[ newSize ]; + System.arraycopy( fileNames, 0, newFileNames, 0, fileNames.length ); + newFileNames[ currentInclusionArraySize++ ] = filename; + currentInclusionArraySize = newSize; + fileNames = newFileNames; + } + } private static IScannerContext sentinel = new SentinelContext(); @@ -65,11 +101,7 @@ public class ContextStack { { int new_size = current_size*2; IScannerContext [] new_cs = new IScannerContext[new_size]; - - for (int i = 0; i < current_size; i++) { - new_cs[i] = cs[i]; - } - + System.arraycopy( cs, 0, new_cs, 0, cs.length ); new_cs[current_size] = c; current_size = new_size; cs = new_cs; @@ -96,6 +128,7 @@ public class ContextStack { public void updateContext(Reader reader, String filename, int type, IASTInclusion inclusion, ISourceElementRequestor requestor, int macroOffset, int macroLength) throws ContextException { int startLine = 1; + int index = -1; // If we expand a macro within a macro, then keep offsets of the top-level one, // as only the top level macro identifier is properly positioned @@ -107,8 +140,13 @@ public class ContextStack { startLine = getCurrentContext().getLine(); } - - IScannerContext context = new ScannerContext( reader, filename, type, null, macroOffset, macroLength, startLine ); + else if( type == IScannerContext.ContextKind.INCLUSION ) + { + addInclusionFilename( filename ); + index = currentInclusionIndex - 1; + } + + IScannerContext context = new ScannerContext( reader, filename, type, null, macroOffset, macroLength, startLine, index ); context.setExtension(inclusion); push( context, requestor ); } @@ -121,7 +159,11 @@ public class ContextStack { TraceUtil.outputTrace(log, "Scanner::ContextStack: entering inclusion ", null, context.getFilename(), null, null ); //$NON-NLS-1$ context.getExtension().enterScope( requestor ); - } + } + else if( context.getKind() == IScannerContext.ContextKind.TOP ) + { + addInclusionFilename( context.getFilename() ); + } // This could be replaced with a check for shouldExpandMacro -- but it is called by // the scanner before this point diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/IScannerContext.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/IScannerContext.java index fe414fe675a..578ef24bdc8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/IScannerContext.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/IScannerContext.java @@ -63,6 +63,8 @@ public interface IScannerContext { public IASTInclusion getExtension(); public void setExtension( IASTInclusion ext ); + + public int getFilenameIndex(); /** * @return diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LimitedScannerContext.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LimitedScannerContext.java index 00034b32cd1..a8bb2a41061 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LimitedScannerContext.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LimitedScannerContext.java @@ -30,8 +30,8 @@ public class LimitedScannerContext * @param object * @param offsetLimit */ - public LimitedScannerContext(Scanner scanner, Reader reader, String string, int kind, int offsetLimit) { - super( reader, string, kind, null ); + public LimitedScannerContext(Scanner scanner, Reader reader, String string, int kind, int offsetLimit, int index ) { + super( reader, string, kind, null, index ); this.scanner = scanner; limit = offsetLimit; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/Scanner.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/Scanner.java index 6240e236e75..f203892ac27 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/Scanner.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/Scanner.java @@ -282,9 +282,9 @@ public class Scanner implements IScanner { try { if( offsetLimit == NO_OFFSET_LIMIT ) - context = new ScannerContext(scannerData.getInitialReader(), resolvedFilename, ScannerContext.ContextKind.TOP, null ); + context = new ScannerContext(scannerData.getInitialReader(), resolvedFilename, ScannerContext.ContextKind.TOP, null, 0 ); else - context = new LimitedScannerContext( this, scannerData.getInitialReader(), resolvedFilename, ScannerContext.ContextKind.TOP, offsetLimit ); + context = new LimitedScannerContext( this, scannerData.getInitialReader(), resolvedFilename, ScannerContext.ContextKind.TOP, offsetLimit, 0 ); scannerData.getContextStack().push( context, scannerData.getClientRequestor() ); } catch( ContextException ce ) { @@ -2132,7 +2132,7 @@ public class Scanner implements IScanner { return newToken( type, buffer.toString()); } - + protected String getCurrentFile() { @@ -3214,4 +3214,20 @@ public class Scanner implements IScanner { buffer.append( "EOF"); //$NON-NLS-1$ return buffer.toString(); } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.parser.IFilenameProvider#getCurrentFileIndex() + */ + public int getCurrentFileIndex() { + IScannerContext mostRelevantFileContext = scannerData.getContextStack().getMostRelevantFileContext(); + return (( mostRelevantFileContext == null ) ? -1 : mostRelevantFileContext.getFilenameIndex() ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.parser.IFilenameProvider#getFilenameForIndex(int) + */ + public String getFilenameForIndex(int index) { + if( index < 0 ) return EMPTY_STRING; + return scannerData.getContextStack().getInclusionFilename(index); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ScannerContext.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ScannerContext.java index 2488100cf6f..e396e9d47a8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ScannerContext.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ScannerContext.java @@ -28,7 +28,7 @@ public class ScannerContext implements IScannerContext /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.parser.IScannerContext#initialize(Reader, String, int, IASTInclusion, int, int, int) */ - public ScannerContext(Reader r, String f, int k, IASTInclusion i, int mO, int mL, int l) + public ScannerContext(Reader r, String f, int k, IASTInclusion i, int mO, int mL, int l, int index) { reader = r; filename = f; @@ -38,14 +38,15 @@ public class ScannerContext implements IScannerContext macroOffset = mO; macroLength = mL; line = l; + this.index = index; } /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.parser.IScannerContext#initialize(Reader, String, int, IASTInclusion) */ - public ScannerContext(Reader r, String f, int k, IASTInclusion i) + public ScannerContext(Reader r, String f, int k, IASTInclusion i, int index) { - this(r, f, k, i, -1, -1, 1); + this(r, f, k, i, -1, -1, 1, index); } public int read() throws IOException { @@ -176,6 +177,7 @@ public class ScannerContext implements IScannerContext } private IASTInclusion inc = null; + private final int index; @@ -191,4 +193,11 @@ public class ScannerContext implements IScannerContext buffer.append( getLine() ); return buffer.toString(); } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.scanner.IScannerContext#getFilenameIndex() + */ + public int getFilenameIndex() { + return index; + } } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/parser/ParserUtil.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/parser/ParserUtil.java index b81ea382970..17f5e14dd45 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/parser/ParserUtil.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/parser/ParserUtil.java @@ -57,13 +57,7 @@ public class ParserUtil // IResource in the workspace try { - IWorkspace workspace = ResourcesPlugin.getWorkspace(); - IPath path = new Path( finalPath ); - - if( workspace.getRoot().getLocation().isPrefixOf( path ) ) - path = path.removeFirstSegments(workspace.getRoot().getLocation().segmentCount() ); - - IResource resultingResource = workspace.getRoot().findMember(path); + IResource resultingResource = getResourceForFilename(finalPath); if( resultingResource != null && resultingResource.getType() == IResource.FILE ) { @@ -85,6 +79,21 @@ public class ParserUtil return InternalParserUtil.createFileReader(finalPath); } + /** + * @param finalPath + * @return + */ + public static IResource getResourceForFilename(String finalPath) { + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + IPath path = new Path( finalPath ); + + if( workspace.getRoot().getLocation().isPrefixOf( path ) ) + path = path.removeFirstSegments(workspace.getRoot().getLocation().segmentCount() ); + + IResource resultingResource = workspace.getRoot().findMember(path); + return resultingResource; + } + /** * @param resultingResource * @param workingCopies @@ -92,7 +101,7 @@ public class ParserUtil */ protected static Reader findWorkingCopy(IResource resultingResource, Iterator workingCopies) { if( parserLogService.isTracing() ) - parserLogService.traceLog( "Attempting to find the working copy for " + resultingResource.getName() ); + parserLogService.traceLog( "Attempting to find the working copy for " + resultingResource.getName() ); //$NON-NLS-1$ while( workingCopies.hasNext() ) { Object next = workingCopies.next(); @@ -102,12 +111,12 @@ public class ParserUtil { CharArrayReader arrayReader = new CharArrayReader( copy.getContents() ); if( parserLogService.isTracing() ) - parserLogService.traceLog( "Working copy found!!" ); + parserLogService.traceLog( "Working copy found!!" ); //$NON-NLS-1$ return new BufferedReader( arrayReader ); } } if( parserLogService.isTracing() ) - parserLogService.traceLog( "Working copy not found." ); + parserLogService.traceLog( "Working copy not found." ); //$NON-NLS-1$ return null; } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/FindAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/FindAction.java index dddd3e2980c..7928ed266cf 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/FindAction.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/FindAction.java @@ -39,6 +39,7 @@ import org.eclipse.cdt.core.parser.ast.IASTFunction; import org.eclipse.cdt.core.parser.ast.IASTMethod; import org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition; import org.eclipse.cdt.core.parser.ast.IASTNode; +import org.eclipse.cdt.core.parser.ast.IASTOffsetableNamedElement; import org.eclipse.cdt.core.parser.ast.IASTVariable; import org.eclipse.cdt.core.search.ICSearchConstants; import org.eclipse.cdt.core.search.ICSearchScope; @@ -183,10 +184,13 @@ public abstract class FindAction extends Action { IFile resourceFile = fEditor.getInputFile(); IParser parser = setupParser(resourceFile); - IASTNode node = null; + IASTOffsetableNamedElement node = null; + IParser.ISelectionParseResult result = null; try{ - node = parser.parse(selectionStart,selectionEnd); + result = parser.parse(selectionStart,selectionEnd); + if( result != null ) + node = result.getOffsetableNamedElement(); } catch (ParseError er){} catch (Exception ex){} @@ -196,12 +200,12 @@ public abstract class FindAction extends Action { } } - if (node == null){ + if (node == null || !( node instanceof IASTNode )){ operationNotAvailableDialog(); return; } - CSearchQuery job = createSearchQuery(selectedText.getText(),getSearchForFromNode(node)); + CSearchQuery job = createSearchQuery(selectedText.getText(),getSearchForFromNode((IASTNode)node)); NewSearchUI.activateSearchResultView(); NewSearchUI.runQuery(job); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsAction.java index 8a0b9a00b7d..486d5c48bab 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsAction.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsAction.java @@ -42,10 +42,11 @@ import org.eclipse.cdt.core.parser.ast.IASTFunction; import org.eclipse.cdt.core.parser.ast.IASTMethod; import org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition; import org.eclipse.cdt.core.parser.ast.IASTNode; +import org.eclipse.cdt.core.parser.ast.IASTOffsetableNamedElement; import org.eclipse.cdt.core.parser.ast.IASTVariable; +import org.eclipse.cdt.core.resources.FileStorage; import org.eclipse.cdt.core.search.BasicSearchResultCollector; import org.eclipse.cdt.core.search.ICSearchConstants; -import org.eclipse.cdt.core.search.ICSearchPattern; import org.eclipse.cdt.core.search.ICSearchScope; import org.eclipse.cdt.core.search.IMatch; import org.eclipse.cdt.core.search.OrPattern; @@ -61,7 +62,11 @@ import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.IWorkingCopyManager; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.Path; import org.eclipse.jface.action.Action; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.ProgressMonitorDialog; @@ -146,6 +151,48 @@ public class OpenDeclarationsAction extends Action implements IUpdate { return null; } } + + private static class Storage + { + private IASTOffsetableNamedElement element; + private IResource resource; + private String fileName; + + public IASTOffsetableNamedElement getNamedElement() + { + return element; + } + /** + * @return Returns the fileName. + */ + public final String getFileName() { + return fileName; + } + /** + * @param fileName The fileName to set. + */ + public final void setFileName(String fileName) { + this.fileName = fileName; + } + /** + * @return Returns the resource. + */ + public final IResource getResource() { + return resource; + } + /** + * @param resource The resource to set. + */ + public final void setResource(IResource resource) { + this.resource = resource; + } + /** + * @param element The element to set. + */ + public final void setElement(IASTOffsetableNamedElement element) { + this.element = element; + } + } /** * @see IAction#actionPerformed */ @@ -156,28 +203,27 @@ public class OpenDeclarationsAction extends Action implements IUpdate { return; } - final ArrayList elementsFound = new ArrayList(); +// final ArrayList elementsFound = new ArrayList(); + final Storage storage = new Storage(); + IRunnableWithProgress runnable = new IRunnableWithProgress() { public void run(IProgressMonitor monitor) { - BasicSearchResultCollector resultCollector = new BasicSearchResultCollector(monitor); - IWorkingCopyManager fManager = CUIPlugin.getDefault().getWorkingCopyManager(); - ITranslationUnit unit = fManager.getWorkingCopy(fEditor.getEditorInput()); - //TODO: Change to Project Scope - ICElement[] projectScopeElement = new ICElement[1]; - projectScopeElement[0] = unit.getCProject();//(ICElement)currentScope.getCProject(); - ICSearchScope scope = SearchEngine.createCSearchScope(projectScopeElement, true); +// IWorkingCopyManager fManager = CUIPlugin.getDefault().getWorkingCopyManager(); +// ITranslationUnit unit = fManager.getWorkingCopy(fEditor.getEditorInput()); IFile resourceFile = fEditor.getInputFile(); IParser parser = setupParser(resourceFile); - - IASTNode node = null; - + int selectionStart = selNode.selStart; + int selectionEnd = selNode.selEnd; + + IParser.ISelectionParseResult result = null; + IASTOffsetableNamedElement node = null; try{ - int selectionStart = selNode.selStart; - int selectionEnd = selNode.selEnd; - node = parser.parse(selectionStart,selectionEnd); + result = parser.parse(selectionStart,selectionEnd); + if( result != null ) + node = result.getOffsetableNamedElement(); } catch (ParseError er){} catch ( VirtualMachineError vmErr){ @@ -191,42 +237,84 @@ public class OpenDeclarationsAction extends Action implements IUpdate { if (node == null){ return; } - - SearchFor searchFor = getSearchForFromNode(node); - ICSearchPattern pattern = SearchEngine.createSearchPattern( selNode.selText,searchFor,ICSearchConstants.DECLARATIONS,true); - - - - try { - searchEngine.search(CUIPlugin.getWorkspace(), pattern, scope, resultCollector, true); - } catch (InterruptedException e) { - } - elementsFound.addAll(resultCollector.getSearchResults()); } + + storage.setFileName( result.getFilename() ); + storage.setElement( node ); + storage.setResource( ParserUtil.getResourceForFilename( result.getFilename() ) ); + return; } }; try { ProgressMonitorDialog progressMonitor = new ProgressMonitorDialog(getShell()); progressMonitor.run(true, true, runnable); - - if (elementsFound.isEmpty() == true) { - //TODO: Get rid of back up search when selection search improves - //MessageDialog.openInformation(getShell(),CSearchMessages.getString("CSearchOperation.operationUnavailable.title"), CSearchMessages.getString("CSearchOperation.operationUnavailable.message")); //$NON-NLS-1$ - temporaryBackUpSearch(); + + if( storage.getResource() != null ) + { + open( storage.getResource(), storage.getNamedElement().getNameOffset(), storage.getNamedElement().getNameEndOffset() - storage.getNamedElement().getNameOffset() ); return; } - - IMatch selected= selectCElement(elementsFound, getShell(), fDialogTitle, fDialogMessage); - if (selected != null) { - open(selected); - return; + else + { + if( open( storage.getFileName(), storage.getNamedElement().getNameOffset(), storage.getNamedElement().getNameEndOffset() - storage.getNamedElement().getNameOffset()) ); + return; } + +// BasicSearchResultCollector resultCollector = new BasicSearchResultCollector(new NullProgressMonitor() ); +// +// SearchFor searchFor = getSearchForFromNode(((IASTNode)storage.getNamedElement())); +// ICSearchPattern pattern = SearchEngine.createSearchPattern( selNode.selText,searchFor,ICSearchConstants.DECLARATIONS,true); +// IWorkingCopyManager fManager = CUIPlugin.getDefault().getWorkingCopyManager(); +// //TODO: Change to Project Scope +// ICElement[] projectScopeElement = new ICElement[1]; +// ITranslationUnit unit = fManager.getWorkingCopy(fEditor.getEditorInput()); +// projectScopeElement[0] = unit.getCProject();//(ICElement)currentScope.getCProject(); +// ICSearchScope scope = SearchEngine.createCSearchScope(projectScopeElement, true); +// +// try { +// searchEngine.search(CUIPlugin.getWorkspace(), pattern, scope, resultCollector, true); +// } catch (InterruptedException e) { +// } +// elementsFound.addAll(resultCollector.getSearchResults()); +// +// +// if (elementsFound.isEmpty() == true) { +// //TODO: Get rid of back up search when selection search improves +// //MessageDialog.openInformation(getShell(),CSearchMessages.getString("CSearchOperation.operationUnavailable.title"), CSearchMessages.getString("CSearchOperation.operationUnavailable.message")); //$NON-NLS-1$ +// temporaryBackUpSearch(); +// return; +// } +// +// IMatch selected= selectCElement(elementsFound, getShell(), fDialogTitle, fDialogMessage); +// if (selected != null) { +// open(selected); +// return; +// } } catch(Exception x) { CUIPlugin.getDefault().log(x); } } + /** + * @param string + * @param i + */ + protected boolean open(String filename, int offset, int length) throws PartInitException, CModelException { + IPath path = new Path( filename ); + IFile file = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path); + if( file != null ) + { + open( file, offset, length ); + return true; + } + + FileStorage storage = new FileStorage(null, path); + IEditorPart part = EditorUtility.openInEditor(storage); + setSelectionAtOffset(part, offset, length); + return true; + + } protected Shell getShell() { return fEditor.getSite().getShell(); } @@ -293,11 +381,25 @@ public class OpenDeclarationsAction extends Action implements IUpdate { } } + protected void open( IMatch element ) throws CModelException, PartInitException + { + open( element.getResource(), element.getStartOffset(), element.getEndOffset() - element.getStartOffset() ); + } + /** * Opens the editor on the given element and subsequently selects it. */ - protected void open(IMatch element) throws CModelException, PartInitException { - IEditorPart part= EditorUtility.openInEditor(element.getResource()); + protected void open( IResource resource, int offset, int length ) throws CModelException, PartInitException { + IEditorPart part= EditorUtility.openInEditor(resource); + setSelectionAtOffset(part, offset, length); + } + + /** + * @param part + * @param offset + * @param length TODO + */ + private void setSelectionAtOffset(IEditorPart part, int offset, int length) { //int line = element.getStartOffset(); //if(line > 0) line--; if(part instanceof CEditor) { @@ -308,11 +410,10 @@ public class OpenDeclarationsAction extends Action implements IUpdate { //if(line > 3) { // ed.selectAndReveal(document.getLineOffset(line - 3), 0); //} - ed.selectAndReveal(element.getStartOffset() /*document.getLineOffset(line)*/, 0); + ed.selectAndReveal(offset, length); } catch (Exception e) {} } } - /** * Shows a dialog for resolving an ambigous C element. * Utility method that can be called by subclassers.