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 fb20aa131b8..0b12218b447 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 @@ -19,7 +19,6 @@ 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; @@ -75,40 +74,54 @@ public class CPPPopulateASTViewAction extends CPPASTVisitor implements IPopulate } private int addRoot(IASTNode node) { - if (monitor != null && monitor.isCanceled()) return PROCESS_ABORT; - if (node == null) return PROCESS_CONTINUE; - - IASTNodeLocation[] nodeLocations = node.getNodeLocations(); - // TODO Devin !(node instanceof ICPPASTLinkageSpecification) below is a hack job for bug 86993 - if (!(node instanceof ICPPASTLinkageSpecification) && !(nodeLocations.length > 0 && - nodeLocations[0].getNodeOffset() >= 0 && - nodeLocations[0].getNodeLength() > 0)) - return PROCESS_CONTINUE; - - DOMASTNodeParent parent = root.findTreeParentForNode(node); - - if (parent == null) - parent = root; - - DOMASTNodeParent tree = new DOMASTNodeParent(node); - parent.addChild(tree); - - // set filter flags - if (node instanceof IASTProblemHolder || node instanceof IASTProblem) { - tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_PROBLEM); - - if (node instanceof IASTProblemHolder) - astProblems = (IASTProblem[])ArrayUtil.append(IASTProblem.class, astProblems, ((IASTProblemHolder)node).getProblem()); - else - astProblems = (IASTProblem[])ArrayUtil.append(IASTProblem.class, astProblems, node); - } - if (node instanceof IASTPreprocessorStatement) - tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_PREPROCESSOR); - if (node instanceof IASTPreprocessorIncludeStatement) - tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_INCLUDE_STATEMENTS); - - return PROCESS_CONTINUE; + if (monitor != null && monitor.isCanceled()) return PROCESS_ABORT; + if (node == null) return PROCESS_CONTINUE; + + // only do length check for ASTNode (getNodeLocations on PreprocessorStatements is very expensive) + if (!(node instanceof ICPPASTLinkageSpecification) && + node instanceof ASTNode && ((ASTNode)node).getLength() <= 0) + return PROCESS_CONTINUE; + + DOMASTNodeParent parent = null; + + // if it's a preprocessor statement being merged then do a special search for parent (no search) + if (node instanceof IASTPreprocessorStatement) { + parent = root; + } else { + IASTNode tempParent = node.getParent(); + if (tempParent instanceof IASTPreprocessorStatement) { + parent = root.findTreeParentForMergedNode(node); + } else { + parent = root.findTreeParentForNode(node); + } + } + + if (parent == null) + parent = root; + + createNode(parent, node); + + return PROCESS_CONTINUE; } + + private void createNode(DOMASTNodeParent parent, IASTNode node) { + DOMASTNodeParent tree = new DOMASTNodeParent(node); + parent.addChild(tree); + + // set filter flags + if (node instanceof IASTProblemHolder || node instanceof IASTProblem) { + tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_PROBLEM); + + if (node instanceof IASTProblemHolder) + astProblems = (IASTProblem[])ArrayUtil.append(IASTProblem.class, astProblems, ((IASTProblemHolder)node).getProblem()); + else + astProblems = (IASTProblem[])ArrayUtil.append(IASTProblem.class, astProblems, node); + } + if (node instanceof IASTPreprocessorStatement) + tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_PREPROCESSOR); + if (node instanceof IASTPreprocessorIncludeStatement) + tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_INCLUDE_STATEMENTS); + } /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processDeclaration(org.eclipse.cdt.core.dom.ast.IASTDeclaration) diff --git a/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/CPopulateASTViewAction.java b/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/CPopulateASTViewAction.java index 268e885f207..88e77ef58b5 100644 --- a/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/CPopulateASTViewAction.java +++ b/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/CPopulateASTViewAction.java @@ -19,7 +19,6 @@ 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; @@ -71,36 +70,50 @@ public class CPopulateASTViewAction extends CASTVisitor implements IPopulateDOMA if (monitor != null && monitor.isCanceled()) return PROCESS_ABORT; if (node == null) return PROCESS_CONTINUE; - IASTNodeLocation[] nodeLocations = node.getNodeLocations(); - if (!(nodeLocations.length > 0 ) ) - return PROCESS_CONTINUE; - - DOMASTNodeParent parent = root.findTreeParentForNode(node); - - if (parent == null) - parent = root; - - DOMASTNodeParent tree = new DOMASTNodeParent(node); - parent.addChild(tree); - - // set filter flags - if (node instanceof IASTProblemHolder || node instanceof IASTProblem) { - tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_PROBLEM); - - if (node instanceof IASTProblemHolder) - astProblems = (IASTProblem[])ArrayUtil.append(IASTProblem.class, astProblems, ((IASTProblemHolder)node).getProblem()); - else - astProblems = (IASTProblem[])ArrayUtil.append(IASTProblem.class, astProblems, node); - } - if (node instanceof IASTPreprocessorStatement) - tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_PREPROCESSOR); - if (node instanceof IASTPreprocessorIncludeStatement) - tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_INCLUDE_STATEMENTS); - - - - return PROCESS_CONTINUE; + // only do length check for ASTNode (getNodeLocations on PreprocessorStatements is very expensive) + if (node instanceof ASTNode && ((ASTNode)node).getLength() <= 0) + return PROCESS_CONTINUE; + + DOMASTNodeParent parent = null; + + // if it's a preprocessor statement being merged then do a special search for parent (no search) + if (node instanceof IASTPreprocessorStatement) { + parent = root; + } else { + IASTNode tempParent = node.getParent(); + if (tempParent instanceof IASTPreprocessorStatement) { + parent = root.findTreeParentForMergedNode(node); + } else { + parent = root.findTreeParentForNode(node); + } + } + + if (parent == null) + parent = root; + + createNode(parent, node); + + return PROCESS_CONTINUE; } + + private void createNode(DOMASTNodeParent parent, IASTNode node) { + DOMASTNodeParent tree = new DOMASTNodeParent(node); + parent.addChild(tree); + + // set filter flags + if (node instanceof IASTProblemHolder || node instanceof IASTProblem) { + tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_PROBLEM); + + if (node instanceof IASTProblemHolder) + astProblems = (IASTProblem[])ArrayUtil.append(IASTProblem.class, astProblems, ((IASTProblemHolder)node).getProblem()); + else + astProblems = (IASTProblem[])ArrayUtil.append(IASTProblem.class, astProblems, node); + } + if (node instanceof IASTPreprocessorStatement) + tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_PREPROCESSOR); + if (node instanceof IASTPreprocessorIncludeStatement) + tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_INCLUDE_STATEMENTS); + } /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processDeclaration(org.eclipse.cdt.core.dom.ast.IASTDeclaration) diff --git a/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMAST.java b/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMAST.java index 499bc663c3d..0d7a418ee83 100644 --- a/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMAST.java +++ b/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMAST.java @@ -45,6 +45,10 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter; import org.eclipse.cdt.core.filetype.ICFileType; import org.eclipse.cdt.core.filetype.ICFileTypeConstants; import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.internal.core.model.CProject; +import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ParserUtil; import org.eclipse.cdt.core.parser.ast.IASTEnumerator; @@ -948,6 +952,7 @@ public class DOMAST extends ViewPart { } private class ASTHighlighterAction extends Action { + private static final String A_PART_INSTANCEOF = "aPart instanceof "; //$NON-NLS-1$ IEditorPart aPart = null; public ASTHighlighterAction(IEditorPart part) { @@ -974,47 +979,54 @@ public class DOMAST extends ViewPart { } public void run() { - ISelection selection = viewer.getSelection(); - Object obj = ((IStructuredSelection) selection).getFirstElement(); - if (obj instanceof DOMASTNodeLeaf) { - String filename = ((DOMASTNodeLeaf) obj).getFilename(); - - if (filename.equals(DOMASTNodeLeaf.BLANK_STRING)) - return; - - IResource r = ParserUtil.getResourceForFilename(filename); - if (r != null) { - try { - aPart = EditorUtility.openInEditor(r); - } catch (PartInitException pie) { - return; - } catch (CModelException e) { - return; - } - } else { - IPath path = new Path( filename ); - FileStorage storage = new FileStorage(null, path); - try { - aPart = EditorUtility.openInEditor(storage); - } catch (PartInitException e) { - return; - } catch (CModelException e) { - return; - } - } - - if( aPart instanceof AbstractTextEditor ) - { - ((AbstractTextEditor) aPart).selectAndReveal(((DOMASTNodeLeaf) obj).getOffset(), - ((DOMASTNodeLeaf) obj).getLength()); - } - else - System.out.println( "aPart instanceof " + aPart.getClass().getName() ); - - aPart.getSite().getPage().activate(aPart.getSite().getPage().findView(VIEW_ID)); - - } - } + ISelection selection = viewer.getSelection(); + Object obj = ((IStructuredSelection) selection).getFirstElement(); + if (obj instanceof DOMASTNodeLeaf) { + if (((DOMASTNodeLeaf)obj).getNode() instanceof IASTTranslationUnit) // don't do anything for TU + return; + + String filename = ((DOMASTNodeLeaf) obj).getFilename(); + + if (filename.equals(DOMASTNodeLeaf.BLANK_STRING)) + return; + + IResource r = ParserUtil.getResourceForFilename(filename); + if (r != null) { + try { + aPart = EditorUtility.openInEditor(r); + } catch (PartInitException pie) { + return; + } catch (CModelException e) { + return; + } + } else { + IPath path = new Path( filename ); + + ICProject cproject = new CProject(null, file.getProject()); + ITranslationUnit unit = CoreModel.getDefault().createTranslationUnitFrom(cproject, path); + if (unit != null) + try { + aPart = EditorUtility.openInEditor(unit); + } catch (PartInitException e) { + return; + } catch (CModelException e) { + return; + } + } + + if( aPart instanceof AbstractTextEditor ) + { + ((AbstractTextEditor) aPart).selectAndReveal(((DOMASTNodeLeaf) obj).getOffset(), + ((DOMASTNodeLeaf) obj).getLength()); + } + else + System.out.println( A_PART_INSTANCEOF + aPart.getClass().getName() ); + + aPart.getSite().getPage().activate(aPart.getSite().getPage().findView(VIEW_ID)); + + } + } + } private class DisplayDeclarationsAction extends DisplaySearchResultAction { diff --git a/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMASTNodeLeaf.java b/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMASTNodeLeaf.java index 40325e11b1f..b3e7378e96c 100644 --- a/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMASTNodeLeaf.java +++ b/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMASTNodeLeaf.java @@ -346,6 +346,9 @@ public class DOMASTNodeLeaf implements IAdaptable { return null; } public IPropertyDescriptor[] getPropertyDescriptors() { + if (node instanceof IASTTranslationUnit) // skip the properties for the TU (too expensive) + return BLANK_DESCRIPTORS; + IPropertyDescriptor[] descriptors = new IPropertyDescriptor[DEFAULT_DESCRIPTOR_SIZE]; if (node instanceof IASTName) { diff --git a/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMASTNodeParent.java b/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMASTNodeParent.java index 8949dff78f9..aac031d2f8b 100644 --- a/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMASTNodeParent.java +++ b/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMASTNodeParent.java @@ -16,6 +16,7 @@ import java.util.Comparator; 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.IASTPreprocessorStatement; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; @@ -24,12 +25,14 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTNode; * @author dsteffle */ public class DOMASTNodeParent extends DOMASTNodeLeaf { + private static final int NO_PREPROCESSOR_STATMENT = -1; private static final DOMASTNodeLeaf[] EMPTY_CHILDREN_ARRAY = new DOMASTNodeLeaf[0]; private static final int DEFAULT_NODE_CHAIN_SIZE = 4; private static final int DEFAULT_CHILDREN_SIZE = 4; int index=0; private DOMASTNodeLeaf[] children; boolean cleanupedElements = false; + private int indexFirstPreproStmnt=NO_PREPROCESSOR_STATMENT; public int getStartSearch() { return index; @@ -45,6 +48,10 @@ public class DOMASTNodeParent extends DOMASTNodeLeaf { children = new DOMASTNodeLeaf[DEFAULT_CHILDREN_SIZE]; } public void addChild(DOMASTNodeLeaf child) { + if (child.getNode() instanceof IASTPreprocessorStatement && indexFirstPreproStmnt == NO_PREPROCESSOR_STATMENT) { + indexFirstPreproStmnt=index; + } + if (index==children.length) { children = (DOMASTNodeLeaf[])ArrayUtil.append(DOMASTNodeLeaf.class, children, child); index++; @@ -64,49 +71,112 @@ public class DOMASTNodeParent extends DOMASTNodeLeaf { child.setParent(null); } - public DOMASTNodeLeaf[] getChildren(boolean cleanupElements) { - if (cleanupElements) { - return getChildren(); - } else { - return children; - } - } - + public DOMASTNodeLeaf[] getChildren(boolean cleanupElements) { + if (cleanupElements) { + return getChildren(); + } + + return children; + } + public DOMASTNodeLeaf [] getChildren() { - // remove null children from the array (if not already done so) - if (!cleanupedElements) { - // remove null elements - children = (DOMASTNodeLeaf[])ArrayUtil.removeNulls(DOMASTNodeLeaf.class, children); - - // sort the elements - Arrays.sort(children, new Comparator() { - public int compare(Object a, Object b) { - if(a instanceof DOMASTNodeLeaf && b instanceof DOMASTNodeLeaf && - ((DOMASTNodeLeaf)a).getNode() instanceof ASTNode && - ((DOMASTNodeLeaf)b).getNode() instanceof ASTNode) { - return ((ASTNode)((DOMASTNodeLeaf)a).getNode()).getOffset() - ((ASTNode)((DOMASTNodeLeaf)b).getNode()).getOffset(); - } - - return 0; - } - }); - - // need to also clean up the children's children, to make sure all nulls are removed (prevent expansion sign when there isn't one) - for(int i=0; i0; } + /** + * Returns the DOMASTNodeParent whose IASTNode is the parent of the IASTNode. + * + * This function is an optimization function used to only search merged preprocessor nodes. + * + * @param node + * @return + */ + public DOMASTNodeParent findTreeParentForMergedNode(IASTNode node) { + if (node == null || node.getParent() == null) return null; + + IASTNode parentToFind = node.getParent(); + + // first check this node before checking children + if (this.getNode() == parentToFind) { + return this; + } + + // build the chain of nodes... and use it to search the tree for the DOMASTNodeParent that owns the node's parent + IASTNode[] nodeChain = new IASTNode[DEFAULT_NODE_CHAIN_SIZE]; + IASTNode topNode = node.getParent(); + ArrayUtil.append(IASTNode.class, nodeChain, node); + nodeChain = (IASTNode[])ArrayUtil.append(IASTNode.class, nodeChain, topNode); + while(topNode.getParent() != null && !(topNode.getParent() instanceof IASTTranslationUnit)) { + topNode = topNode.getParent(); + nodeChain = (IASTNode[])ArrayUtil.append(IASTNode.class, nodeChain, topNode); + } + + // loop through the chain of nodes and use it to only search the necessary children required to find the node + DOMASTNodeLeaf[] childrenToSearch = children; + int j=childrenToSearch.length-1; + outerLoop: for(int i=nodeChain.length-1; i>=0; i--) { + if (nodeChain[i] != null) { + parentToFind = nodeChain[i]; + + for(; j>=indexFirstPreproStmnt; j--) { + if (childrenToSearch[j] instanceof DOMASTNodeParent) { + if ( childrenToSearch[j].getNode() == node.getParent() ) { + return (DOMASTNodeParent)childrenToSearch[j]; + } + + if (childrenToSearch[j].getNode() == parentToFind) { + int pos = j; + j = ((DOMASTNodeParent)childrenToSearch[pos]).getStartSearch(); + childrenToSearch = ((DOMASTNodeParent)childrenToSearch[pos]).getChildren(false); + continue outerLoop; + } + } + } + } + } + + return null; // nothing found + } + /** * Returns the DOMASTNodeParent whose IASTNode is the parent of the IASTNode. *