diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java index 9e87073a028..9f2d9d56ec0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java @@ -61,9 +61,7 @@ public interface IASTTranslationUnit extends IASTNode { public IASTNodeLocation[] getLocationInfo(int offset, int length); - public IASTNode[] selectNodesForLocation(String path, int offset, int length); - - public IASTNode[] selectNodesForLocation(int offset, int length); + public IASTNode selectNodeForLocation(String path, int offset, int length); public IASTPreprocessorMacroDefinition[] getMacroDefinitions(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTranslationUnit.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTranslationUnit.java index 3c8d7419e22..3b06bb5d60d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTranslationUnit.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTranslationUnit.java @@ -11,20 +11,34 @@ package org.eclipse.cdt.internal.core.dom.parser.c; import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; +import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTArrayModifier; +import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTExpression; +import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; +import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTPointerOperator; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement; import org.eclipse.cdt.core.dom.ast.IASTProblem; +import org.eclipse.cdt.core.dom.ast.IASTStatement; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IASTVisitor; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.c.ICASTDesignator; +import org.eclipse.cdt.core.parser.ast.IASTEnumerator; +import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.IRequiresLocationInformation; import org.eclipse.cdt.internal.core.parser.scanner2.ILocationResolver; +import org.eclipse.cdt.internal.core.parser.scanner2.InvalidPreprocessorNodeException; /** * @author jcamelon @@ -126,13 +140,172 @@ public class CASTTranslationUnit extends CASTNode implements IASTTranslationUnit return resolver.getLocations(offset,length); } + private class CFindNodeForOffsetAction extends CVisitor.CBaseVisitorAction { + { + processNames = true; + processDeclarations = true; + processInitializers = true; + processParameterDeclarations = true; + processDeclarators = true; + processDeclSpecifiers = true; + processDesignators = true; + processExpressions = true; + processStatements = true; + processTypeIds = true; + processEnumerators = true; + } + + IASTNode foundNode = null; + int offset = 0; + int length = 0; + + /** + * + */ + public CFindNodeForOffsetAction(int offset, int length) { + this.offset = offset; + this.length = length; + } + + public int processNode(IASTNode node) { + if (foundNode != null) + return PROCESS_ABORT; + + if (node instanceof ASTNode && + ((ASTNode)node).getOffset() == offset && + ((ASTNode)node).getLength() == length) { + foundNode = node; + return PROCESS_ABORT; + } + + // skip the rest of this node if the selection is outside of its bounds + if (node instanceof ASTNode && + offset > ((ASTNode)node).getOffset() + ((ASTNode)node).getLength()) + return PROCESS_SKIP; + + return PROCESS_CONTINUE; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processDeclaration(org.eclipse.cdt.core.dom.ast.IASTDeclaration) + */ + public int processDeclaration(IASTDeclaration declaration) { + // use declarations to determine if the search has gone past the offset (i.e. don't know the order the visitor visits the nodes) + if (declaration instanceof ASTNode && ((ASTNode)declaration).getOffset() > offset) + return PROCESS_ABORT; + + return processNode(declaration); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processDeclarator(org.eclipse.cdt.core.dom.ast.IASTDeclarator) + */ + public int processDeclarator(IASTDeclarator declarator) { + int ret = processNode(declarator); + + IASTPointerOperator[] ops = declarator.getPointerOperators(); + for(int i=0; i= 0) { + CFindNodeForOffsetAction nodeFinder = new CFindNodeForOffsetAction(globalOffset, realLength); + getVisitor().visitTranslationUnit(nodeFinder); + node = nodeFinder.getNode(); + } + } + + return node; } @@ -189,13 +362,6 @@ public class CASTTranslationUnit extends CASTNode implements IASTTranslationUnit this.resolver = resolver; } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IASTTranslationUnit#selectNodesForLocation(int, int) - */ - public IASTNode[] selectNodesForLocation(int offset, int length) { - return selectNodesForLocation( "", offset, length ); //$NON-NLS-1$ - } /* (non-Javadoc) * @see java.lang.Object#finalize() diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java index f47fb959bde..dc695cab491 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java @@ -11,24 +11,42 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; +import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTArrayModifier; +import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTExpression; +import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; +import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTPointerOperator; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement; import org.eclipse.cdt.core.dom.ast.IASTProblem; +import org.eclipse.cdt.core.dom.ast.IASTStatement; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IASTVisitor; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.c.ICASTDesignator; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionTryBlockDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisitor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; +import org.eclipse.cdt.core.parser.ast.IASTEnumerator; +import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.IRequiresLocationInformation; import org.eclipse.cdt.internal.core.parser.scanner2.ILocationResolver; +import org.eclipse.cdt.internal.core.parser.scanner2.InvalidPreprocessorNodeException; /** * @author jcamelon @@ -146,13 +164,189 @@ public class CPPASTTranslationUnit extends CPPASTNode implements return resolver.getLocations(offset, length); } + private class CPPFindNodeForOffsetAction extends CPPVisitor.CPPBaseVisitorAction { + { + processNames = true; + processDeclarations = true; + processInitializers = true; + processParameterDeclarations = true; + processDeclarators = true; + processDeclSpecifiers = true; + processExpressions = true; + processStatements = true; + processTypeIds = true; + processEnumerators = true; + processBaseSpecifiers = true; + processNamespaces = true; + } + + IASTNode foundNode = null; + int offset = 0; + int length = 0; + + /** + * + */ + public CPPFindNodeForOffsetAction(int offset, int length) { + this.offset = offset; + this.length = length; + } + + public int processNode(IASTNode node) { + if (foundNode != null) + return PROCESS_ABORT; + + if (node instanceof ASTNode && + ((ASTNode)node).getOffset() == offset && + ((ASTNode)node).getLength() == length) { + foundNode = node; + return PROCESS_ABORT; + } + + // skip the rest of this node if the selection is outside of its bounds + if (node instanceof ASTNode && + offset > ((ASTNode)node).getOffset() + ((ASTNode)node).getLength()) + return PROCESS_SKIP; + + return PROCESS_CONTINUE; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processDeclaration(org.eclipse.cdt.core.dom.ast.IASTDeclaration) + */ + public int processDeclaration(IASTDeclaration declaration) { + // use declarations to determine if the search has gone past the offset (i.e. don't know the order the visitor visits the nodes) + if (declaration instanceof ASTNode && ((ASTNode)declaration).getOffset() > offset) + return PROCESS_ABORT; + + return processNode(declaration); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processDeclarator(org.eclipse.cdt.core.dom.ast.IASTDeclarator) + */ + public int processDeclarator(IASTDeclarator declarator) { + int ret = processNode(declarator); + + IASTPointerOperator[] ops = declarator.getPointerOperators(); + for(int i=0; i= 0) { + CPPFindNodeForOffsetAction nodeFinder = new CPPFindNodeForOffsetAction(globalOffset, realLength); + getVisitor().visitTranslationUnit(nodeFinder); + node = nodeFinder.getNode(); + } + } + + return node; } /* @@ -213,19 +407,6 @@ public class CPPASTTranslationUnit extends CPPASTNode implements this.resolver = resolver; } - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.core.dom.ast.IASTTranslationUnit#selectNodesForLocation(int, - * int) - */ - public IASTNode[] selectNodesForLocation(int offset, int length) { - if (resolver == null) - return EMPTY_NODE_ARRAY; - return selectNodesForLocation(resolver.getTranslationUnitPath(), - offset, length); //$NON-NLS-1$ - } - /* * (non-Javadoc) * diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ILocationResolver.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ILocationResolver.java index 3284547a3c4..d949b433093 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ILocationResolver.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ILocationResolver.java @@ -10,6 +10,7 @@ **********************************************************************/ package org.eclipse.cdt.internal.core.parser.scanner2; +import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition; import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement; @@ -26,7 +27,6 @@ public interface ILocationResolver { public IASTPreprocessorStatement [] getAllPreprocessorStatements(); public IASTNodeLocation [] getLocations( int offset, int length ); - public IASTNodeLocation getLocation( int offset ); public char [] getUnpreprocessedSignature( IASTNodeLocation [] locations ); @@ -35,5 +35,7 @@ public interface ILocationResolver { public String getTranslationUnitPath(); public void cleanup(); + + public IASTNode getPreprocessorNode( String path, int offset, int length ) throws InvalidPreprocessorNodeException; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/InvalidPreprocessorNodeException.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/InvalidPreprocessorNodeException.java new file mode 100644 index 00000000000..b3985767999 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/InvalidPreprocessorNodeException.java @@ -0,0 +1,36 @@ +/********************************************************************** + * Copyright (c) 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.internal.core.parser.scanner2; + +/** + * @author dsteffle + */ +public class InvalidPreprocessorNodeException extends Exception { + + public InvalidPreprocessorNodeException(String message) { + super(message); + } + + public InvalidPreprocessorNodeException(String message, int offset) { + super(message); + globalOffset = offset; + } + + private int globalOffset = -1; + + public int getGlobalOffset() { + return globalOffset; + } + + public void setGlobalOffset(int offset) { + globalOffset = offset; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/LocationMap.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/LocationMap.java index fc453676ef4..8cb06621bd7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/LocationMap.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/LocationMap.java @@ -46,7 +46,9 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTNode; */ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { - /** + private static final String NOT_VALID_MACRO = "Not a valid macro selection"; //$NON-NLS-1$ + private static final String TU_INCLUDE_NOT_FOUND = "File searching does not match TU or #includes."; //$NON-NLS-1$ + /** * @author jcamelon */ static class ASTEndif extends ScannerASTNode implements @@ -1024,32 +1026,39 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { collectContexts(V_PREPROCESSOR, tu, contexts, 0); IASTPreprocessorStatement[] result = new IASTPreprocessorStatement[size]; for (int i = 0; i < size; ++i) { - if (contexts[i] instanceof _Inclusion) - result[i] = createASTInclusion(((_Inclusion) contexts[i])); - else if (contexts[i] instanceof _MacroDefinition) - result[i] = createASTMacroDefinition((_MacroDefinition) contexts[i]); - else if (contexts[i] instanceof _Undef) - result[i] = createASTUndef((_Undef) contexts[i]); - else if (contexts[i] instanceof _Pragma) - result[i] = createASTPragma((_Pragma) contexts[i]); - else if (contexts[i] instanceof _Error) - result[i] = createASTError((_Error) contexts[i]); - else if (contexts[i] instanceof _If) - result[i] = createASTIf((_If) contexts[i]); - else if (contexts[i] instanceof _Ifdef) - result[i] = createASTIfdef((_Ifdef) contexts[i]); - else if (contexts[i] instanceof _Ifndef) - result[i] = createASTIfndef((_Ifndef) contexts[i]); - else if (contexts[i] instanceof _Else) - result[i] = createASTElse((_Else) contexts[i]); - else if (contexts[i] instanceof _Elif) - result[i] = createASTElif((_Elif) contexts[i]); - else if (contexts[i] instanceof _Endif) - result[i] = createASTEndif((_Endif) contexts[i]); + result[i] = createPreprocessorStatement(contexts[i]); } return result; } + + private IASTPreprocessorStatement createPreprocessorStatement(_Context context) { + IASTPreprocessorStatement result = null; + if (context instanceof _Inclusion) + result = createASTInclusion(((_Inclusion) context)); + else if (context instanceof _MacroDefinition) + result = createASTMacroDefinition((_MacroDefinition) context); + else if (context instanceof _Undef) + result = createASTUndef((_Undef) context); + else if (context instanceof _Pragma) + result = createASTPragma((_Pragma) context); + else if (context instanceof _Error) + result = createASTError((_Error) context); + else if (context instanceof _If) + result = createASTIf((_If) context); + else if (context instanceof _Ifdef) + result = createASTIfdef((_Ifdef) context); + else if (context instanceof _Ifndef) + result = createASTIfndef((_Ifndef) context); + else if (context instanceof _Else) + result = createASTElse((_Else) context); + else if (context instanceof _Elif) + result = createASTElif((_Elif) context); + else if (context instanceof _Endif) + result = createASTEndif((_Endif) context); + + return result; + } /** * @param endif @@ -1280,16 +1289,6 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { return bestContext; } - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.internal.core.parser.scanner2.ILocationResolver#getLocation(int) - */ - public IASTNodeLocation getLocation(int offset) { - // TODO Auto-generated method stub - return null; - } - /* * (non-Javadoc) * @@ -1693,5 +1692,94 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog { currentContext.addSubContext(new _Ifndef(currentContext, startOffset, endOffset, taken)); } + + private _Context findInclusion(_CompositeContext context, String path) { + _Context foundContext = null; + List contexts = context.getSubContexts(); + + for (int i=0; foundContext == null && i context.context_directive_end) { + globalOffset += context.context_ends - context.context_directive_end; + } + + // check if the _Context is the selection + if (globalOffset == context.context_directive_start && + length == context.context_directive_end - context.context_directive_start) { + result = createPreprocessorStatement(context); + } + + // check if a sub node of the macro is the selection // TODO determine how this can be kept in sync with logic in getAllPreprocessorStatements (i.e. 1:1 mapping) + if (context instanceof _MacroDefinition) { + if (globalOffset == ((_MacroDefinition)context).nameOffset + && length == ((_MacroDefinition)context).name.length) + result = createASTMacroDefinition((_MacroDefinition)context).getName(); + } + + // stop searching the _Contexts if they've gone past the selection + if (globalOffset < context.context_directive_end) + break; + } + } + + if (result == null) + throw new InvalidPreprocessorNodeException(NOT_VALID_MACRO, globalOffset); + + return result; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.scanner2.ILocationResolver#getPreprocessorNode(int, int) + */ + public IASTNode getPreprocessorNode(String path, int offset, int length) throws InvalidPreprocessorNodeException { + IASTNode result = null; + int globalOffset = 0; + _Context foundContext = tu; + + // is the selection in TU or an #include else it's an exception + if (CharArrayUtils.equals(tu.reader.filename, path.toCharArray())) { + globalOffset = offset; // in TU so start at the real offset + } else { + foundContext = findInclusion(tu, path); + + if (foundContext == null) { + throw new InvalidPreprocessorNodeException(TU_INCLUDE_NOT_FOUND, globalOffset); + } else if (foundContext instanceof _Inclusion){ + globalOffset = foundContext.context_directive_end + offset; // start at #include's directive_end + real offset + } + } + + result = getPreprocessorNode(globalOffset, length, foundContext); + + if (result == null) + throw new InvalidPreprocessorNodeException(NOT_VALID_MACRO, globalOffset); + + return result; + } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.ui.tests/plugin.xml b/core/org.eclipse.cdt.ui.tests/plugin.xml index de56ee8b84d..1f8d3e2181e 100644 --- a/core/org.eclipse.cdt.ui.tests/plugin.xml +++ b/core/org.eclipse.cdt.ui.tests/plugin.xml @@ -92,6 +92,15 @@ + + + diff --git a/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/CPPPopulateASTViewAction.java b/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/CPPPopulateASTViewAction.java index 47410f1d0b6..bbdc5ad34c0 100644 --- a/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/CPPPopulateASTViewAction.java +++ b/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/CPPPopulateASTViewAction.java @@ -263,7 +263,7 @@ public class CPPPopulateASTViewAction extends CPPBaseVisitorAction implements IP TreeParent[] treeIncludes = new TreeParent[includes.length]; for (int i=0; i - * The view uses a label provider to define how model objects should be - * presented in the view. Each view can present the same model objects using - * different labels and icons, if needed. Alternatively, a single label provider - * can be shared between views in order to ensure that objects of the same type - * are presented in the same way everywhere. - *

+ * This is a simple DOM AST View used for development testing. */ public class DOMAST extends ViewPart { - private static final String DOM_AST_HAS_NO_CONTENT = "DOM AST has no content"; //$NON-NLS-1$ - private static final String SEARCH_FOR_IASTNAME = "Search for IASTName"; //$NON-NLS-1$ - private static final String CLEAR = "Clear"; //$NON-NLS-1$ - private static final String DOMAST_FILTER_GROUP_ID = "org.eclipse.cdt.ui.tests.DOMAST.DOMASTFilterGroup"; //$NON-NLS-1$ + private static final String NOT_VALID_COMPILATION_UNIT = "The active editor does not contain a valid compilation unit."; //$NON-NLS-1$ private static final String EXTENSION_CXX = "CXX"; //$NON-NLS-1$ private static final String EXTENSION_CPP = "CPP"; //$NON-NLS-1$ private static final String EXTENSION_CC = "CC"; //$NON-NLS-1$ private static final String EXTENSION_C = "C"; //$NON-NLS-1$ - private static final String NOT_VALID_COMPILATION_UNIT = "The active editor does not contain a valid compilation unit."; //$NON-NLS-1$ + private static final String DOM_AST_HAS_NO_CONTENT = "DOM AST has no content"; //$NON-NLS-1$ + private static final String SEARCH_FOR_IASTNAME = "Search for IASTName"; //$NON-NLS-1$ + private static final String CLEAR = "Clear"; //$NON-NLS-1$ + private static final String DOMAST_FILTER_GROUP_ID = "org.eclipse.cdt.ui.tests.DOMAST.DOMASTFilterGroup"; //$NON-NLS-1$ private static final String LOAD_ACTIVE_EDITOR = "Load Active Editor"; //$NON-NLS-1$ private static final String COLLAPSE_ALL = "Collapse ALL"; //$NON-NLS-1$ private static final String EXPAND_ALL = "Expand All"; //$NON-NLS-1$ private static final String REFRESH_DOM_AST = "Refresh DOM AST"; //$NON-NLS-1$ - private static final String VIEW_NAME = "DOM View"; //$NON-NLS-1$ + public static final String VIEW_NAME = "DOM View"; //$NON-NLS-1$ private static final String POPUPMENU = "#PopupMenu"; //$NON-NLS-1$ private static final String OPEN_DECLARATIONS = "Open Declarations"; //$NON-NLS-1$ private static final String OPEN_REFERENCES = "Open References"; //$NON-NLS-1$ @@ -144,6 +137,8 @@ public class DOMAST extends ViewPart { private ParserLanguage lang = null; private CustomFiltersActionGroup customFiltersActionGroup; + + private static ViewContentProvider.StartInitializingASTView initializeASTViewJob = null; /* * The content provider class is responsible for providing objects to the @@ -167,8 +162,8 @@ public class DOMAST extends ViewPart { } public ViewContentProvider(IFile file, Object[] expanded) { - StartInitializingASTView job = new StartInitializingASTView(new InitializeView(POPULATING_AST_VIEW, this, viewer, file), expanded); - job.schedule(); + initializeASTViewJob = new StartInitializingASTView(new InitializeView(POPULATING_AST_VIEW, this, viewer, file), expanded); + initializeASTViewJob.schedule(); } @@ -177,6 +172,7 @@ public class DOMAST extends ViewPart { for(int i=0; i= 0))) { foundName = findNextMatchingName( findString, searchForward, caseSensitive, wholeWord, regExSearch ); - treeNode = tuTreeParent.findTreeObjectForIASTName(foundName); + treeNode = tuTreeParent.findTreeObject(foundName, true, true); if (treeNode != null && treeNode.getParent() != null) { // found a matching TreeObject, so expand the tree to that object - treeItem = expandTreeToTreeObject(treeNode); // TODO Devin test this + treeItem = expandTreeToTreeObject(treeNode); } } @@ -440,5 +441,5 @@ public class FindIASTNameTarget implements IFindReplaceTarget, IFindReplaceTarge // TODO Auto-generated method stub } - + } diff --git a/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/OpenDOMViewAction.java b/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/OpenDOMViewAction.java index 4fde41043d3..58328a8bf04 100644 --- a/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/OpenDOMViewAction.java +++ b/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/OpenDOMViewAction.java @@ -116,5 +116,5 @@ public class OpenDOMViewAction implements IViewActionDelegate, IEditorActionDele */ public void setActivePart(IAction action, IWorkbenchPart targetPart) { } - + } diff --git a/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/ShowInDOMViewAction.java b/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/ShowInDOMViewAction.java new file mode 100644 index 00000000000..223b27b97f2 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/ShowInDOMViewAction.java @@ -0,0 +1,173 @@ +/********************************************************************** + * Copyright (c) 2005 IBM Canada and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.ui.tests.DOMAST; + +import org.eclipse.cdt.core.dom.ast.IASTFileLocation; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; +import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.internal.ui.editor.CEditor; +import org.eclipse.cdt.internal.ui.util.ExternalEditorInput; +import org.eclipse.cdt.ui.testplugin.CTestPlugin; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IStorage; +import org.eclipse.core.runtime.IPath; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.text.TextSelection; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.swt.widgets.Event; +import org.eclipse.ui.IEditorActionDelegate; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.actions.ActionDelegate; + +/** + * @author dsteffle + */ +public class ShowInDOMViewAction extends ActionDelegate implements + IEditorActionDelegate { + + CEditor editor = null; + IASTTranslationUnit tu = null; + IViewPart view = null; + String file = null; + + /* (non-Javadoc) + * @see org.eclipse.ui.IEditorActionDelegate#setActiveEditor(org.eclipse.jface.action.IAction, org.eclipse.ui.IEditorPart) + */ + public void setActiveEditor(IAction action, IEditorPart targetEditor) { + if (targetEditor instanceof CEditor) + editor = (CEditor)targetEditor; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.actions.ActionDelegate#runWithEvent(org.eclipse.jface.action.IAction, org.eclipse.swt.widgets.Event) + */ + public void runWithEvent(IAction action, Event event) { + TextSelection selection = null; + + if (editor != null && + editor.getSelectionProvider().getSelection() instanceof TextSelection) { + selection = (TextSelection)editor.getSelectionProvider().getSelection(); + } + if (selection != null) { + if (!isFileInView()) { + view = DOMAST.openDOMASTViewRunAction(editor, new FindDisplayNode(selection.getOffset(), selection.getLength()), "Find Node in AST DOM View"); + } else { + new FindDisplayNode(selection.getOffset(), selection.getLength()).run(); + } + } + } + + private void showMessage(String message) { + MessageDialog.openInformation(CTestPlugin.getStandardDisplay().getActiveShell(), DOMAST.VIEW_NAME, message); + } + + private boolean isFileInView() { + if( editor.getInputFile() != null ) + file = editor.getInputFile().getLocation().toOSString(); + else + { + if( editor.getEditorInput() instanceof ExternalEditorInput ) + file = ((ExternalEditorInput)editor.getEditorInput()).getStorage().getFullPath().toOSString(); + } + + if (file == null) return false; + + try { + view = editor.getSite().getPage().showView(OpenDOMViewAction.VIEW_ID); + } catch (PartInitException pie) {} + + if (view != null) { + if (view instanceof DOMAST) { + IContentProvider provider = ((DOMAST)view).getContentProvider(); + if (provider != null && provider instanceof DOMAST.ViewContentProvider) { + tu = ((DOMAST.ViewContentProvider)provider).getTU(); + + if (tu != null) { + String fileName = null; + + // check if file is tu + IASTNodeLocation[] locs = tu.getNodeLocations(); + for (int i=0; i