1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

binary search for finding nodes in the DOM AST view

This commit is contained in:
Andrew Niefer 2005-05-12 16:20:31 +00:00
parent d333b65022
commit 2d27b6de65
2 changed files with 92 additions and 34 deletions

View file

@ -47,6 +47,7 @@ import org.eclipse.cdt.core.dom.ast.c.ICASTPointer;
import org.eclipse.cdt.core.dom.ast.gnu.c.IGCCASTArrayRangeDesignator;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointer;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.ui.views.properties.IPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertySource;
@ -324,6 +325,16 @@ public class DOMASTNodeLeaf implements IAdaptable {
return filterFlag;
}
public int relativeNodePosition( IASTNode n ){
ASTNode astNode = (ASTNode) n;
ASTNode thisNode = (ASTNode) getNode();
if( thisNode.getOffset() > astNode.getOffset() )
return -1;
if( (thisNode.getOffset() + thisNode.getLength()) < (astNode.getOffset() + astNode.getLength()) )
return 1;
return 0;
}
private static class ASTPropertySource implements IPropertySource {
private static final String DOMEXCEPTION_THIS_METHOD_ISN_T_SUPPORTED_BY_THIS_OBJECT = "DOMException - this method isn't supported by this Object"; //$NON-NLS-1$
private static final String FLUSH_CACHE_METHOD_NAME = "flushCache"; //$NON-NLS-1$

View file

@ -240,6 +240,22 @@ public class DOMASTNodeParent extends DOMASTNodeLeaf {
return null; // nothing found
}
public int relativeNodePosition( IASTNode n ){
ASTNode astNode = (ASTNode) n;
if( !cleanupedElements ){
cleanChildren();
}
if( children.length > 0 ){
ASTNode first = (ASTNode) children[0].getNode();
if( first.getOffset() > astNode.getOffset() )
return -1;
ASTNode last = (ASTNode) children[ children.length - 1 ].getNode();
if( (last.getOffset() + last.getLength()) < (astNode.getOffset() + astNode.getLength()) )
return 1;
return 0;
}
return super.relativeNodePosition( n );
}
/**
* Returns the DOMASTNodeParent that corresponds to the IASTNode. This is the DOMASTNodeParent
* that represents the IASTNode in the DOM AST View.
@ -250,50 +266,81 @@ public class DOMASTNodeParent extends DOMASTNodeLeaf {
public DOMASTNodeParent findTreeObject(IASTNode node, boolean useOffset) {
if (node == null) return null;
IASTNode nodeToFind = node;
// first check this node before checking children
if (equalNodes(node, this.getNode(), useOffset)) {
return this;
}
// build the chain of nodes... and use it to search the tree for the DOMASTNodeParent that contains the node
IASTNode[] nodeChain = new IASTNode[DEFAULT_NODE_CHAIN_SIZE];
IASTNode topNode = node;
nodeChain = (IASTNode[])ArrayUtil.append(IASTNode.class, nodeChain, topNode);
while(topNode.getParent() != null && !(topNode.getParent() instanceof IASTTranslationUnit)) {
topNode = topNode.getParent();
if( !useOffset || node instanceof IASTPreprocessorStatement) {
IASTNode nodeToFind = node;
// build the chain of nodes... and use it to search the tree for the DOMASTNodeParent that contains the node
IASTNode[] nodeChain = new IASTNode[DEFAULT_NODE_CHAIN_SIZE];
IASTNode topNode = 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;
outerLoop: for(int i=nodeChain.length-1; i>=0; i--) {
if (nodeChain[i] != null) {
nodeToFind = nodeChain[i];
// loop through the chain of nodes and use it to only search the necessary children required to find the node
DOMASTNodeLeaf[] childrenToSearch = children;
outerLoop: for(int i=nodeChain.length-1; i>=0; i--) {
if (nodeChain[i] != null) {
nodeToFind = nodeChain[i];
for(int j=0; j<childrenToSearch.length; j++) {
if (childrenToSearch[j] instanceof DOMASTNodeParent) {
for(int j=0; j<childrenToSearch.length; j++) {
if (childrenToSearch[j] instanceof DOMASTNodeParent) {
if ( equalNodes(childrenToSearch[j].getNode(), node, useOffset) ) {
return (DOMASTNodeParent)childrenToSearch[j];
}
if ( equalNodes(childrenToSearch[j].getNode(), node, useOffset) ) {
return (DOMASTNodeParent)childrenToSearch[j];
}
if ( equalNodes(childrenToSearch[j].getNode(), nodeToFind, useOffset) ) {
childrenToSearch = ((DOMASTNodeParent)childrenToSearch[j]).getChildren(false);
continue outerLoop;
}
if ( equalNodes(childrenToSearch[j].getNode(), nodeToFind, useOffset) ) {
childrenToSearch = ((DOMASTNodeParent)childrenToSearch[j]).getChildren(false);
continue outerLoop;
}
// since the nodeChain doesn't include #includes, if an #include is encountered then search it's children
if (childrenToSearch[j].getNode() instanceof IASTPreprocessorIncludeStatement) {
DOMASTNodeParent foundParentInInclude = ((DOMASTNodeParent)childrenToSearch[j]).findTreeObject(node, useOffset);
if(foundParentInInclude != null) {
return foundParentInInclude;
// since the nodeChain doesn't include #includes, if an #include is encountered then search it's children
if (childrenToSearch[j].getNode() instanceof IASTPreprocessorIncludeStatement) {
DOMASTNodeParent foundParentInInclude = ((DOMASTNodeParent)childrenToSearch[j]).findTreeObject(node, useOffset);
if(foundParentInInclude != null) {
return foundParentInInclude;
}
}
}
}
}
}
} else {
if( children.length == 0 )
return null;
if( !cleanupedElements ){
cleanChildren();
}
int a = 0, z = children.length - 1;
int idx = (z - a) / 2 ;
while( true ){
int compare = children[ idx ].relativeNodePosition( node );
if( compare == 0 ){
if( children[idx] instanceof DOMASTNodeParent ){
return ((DOMASTNodeParent)children[idx]).findTreeObject( node, useOffset );
}
return null; //??
} else if( compare == -1 )
z = idx;
else
a = idx;
int diff = z - a;
if( diff == 0 )
return null;
else if( diff == 1 )
idx = ( idx == z ) ? a : z;
else
idx = a + ( z - a ) / 2;
if( z == a )
return null;
if( z - a == 1 && children[ a ].relativeNodePosition( node ) == 1 && children[ z ].relativeNodePosition( node ) == -1 )
return null;
}
}
return null; // nothing found