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

Patch for Devin Steffler.

FIXED 91233: DOM AST Viewer gets stuck on C stdio
This commit is contained in:
John Camelon 2005-04-15 13:51:21 +00:00
parent f9a0362d08
commit 81d46bfbf6
5 changed files with 253 additions and 142 deletions

View file

@ -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.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; 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.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator; import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
@ -78,18 +77,34 @@ public class CPPPopulateASTViewAction extends CPPASTVisitor implements IPopulate
if (monitor != null && monitor.isCanceled()) return PROCESS_ABORT; if (monitor != null && monitor.isCanceled()) return PROCESS_ABORT;
if (node == null) return PROCESS_CONTINUE; if (node == null) return PROCESS_CONTINUE;
IASTNodeLocation[] nodeLocations = node.getNodeLocations(); // only do length check for ASTNode (getNodeLocations on PreprocessorStatements is very expensive)
// TODO Devin !(node instanceof ICPPASTLinkageSpecification) below is a hack job for bug 86993 if (!(node instanceof ICPPASTLinkageSpecification) &&
if (!(node instanceof ICPPASTLinkageSpecification) && !(nodeLocations.length > 0 && node instanceof ASTNode && ((ASTNode)node).getLength() <= 0)
nodeLocations[0].getNodeOffset() >= 0 &&
nodeLocations[0].getNodeLength() > 0))
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
DOMASTNodeParent parent = root.findTreeParentForNode(node); 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) if (parent == null)
parent = root; parent = root;
createNode(parent, node);
return PROCESS_CONTINUE;
}
private void createNode(DOMASTNodeParent parent, IASTNode node) {
DOMASTNodeParent tree = new DOMASTNodeParent(node); DOMASTNodeParent tree = new DOMASTNodeParent(node);
parent.addChild(tree); parent.addChild(tree);
@ -106,8 +121,6 @@ public class CPPPopulateASTViewAction extends CPPASTVisitor implements IPopulate
tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_PREPROCESSOR); tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_PREPROCESSOR);
if (node instanceof IASTPreprocessorIncludeStatement) if (node instanceof IASTPreprocessorIncludeStatement)
tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_INCLUDE_STATEMENTS); tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_INCLUDE_STATEMENTS);
return PROCESS_CONTINUE;
} }
/* (non-Javadoc) /* (non-Javadoc)

View file

@ -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.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; 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.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator; import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
@ -71,15 +70,33 @@ public class CPopulateASTViewAction extends CASTVisitor implements IPopulateDOMA
if (monitor != null && monitor.isCanceled()) return PROCESS_ABORT; if (monitor != null && monitor.isCanceled()) return PROCESS_ABORT;
if (node == null) return PROCESS_CONTINUE; if (node == null) return PROCESS_CONTINUE;
IASTNodeLocation[] nodeLocations = node.getNodeLocations(); // only do length check for ASTNode (getNodeLocations on PreprocessorStatements is very expensive)
if (!(nodeLocations.length > 0 ) ) if (node instanceof ASTNode && ((ASTNode)node).getLength() <= 0)
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
DOMASTNodeParent parent = root.findTreeParentForNode(node); 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) if (parent == null)
parent = root; parent = root;
createNode(parent, node);
return PROCESS_CONTINUE;
}
private void createNode(DOMASTNodeParent parent, IASTNode node) {
DOMASTNodeParent tree = new DOMASTNodeParent(node); DOMASTNodeParent tree = new DOMASTNodeParent(node);
parent.addChild(tree); parent.addChild(tree);
@ -96,10 +113,6 @@ public class CPopulateASTViewAction extends CASTVisitor implements IPopulateDOMA
tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_PREPROCESSOR); tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_PREPROCESSOR);
if (node instanceof IASTPreprocessorIncludeStatement) if (node instanceof IASTPreprocessorIncludeStatement)
tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_INCLUDE_STATEMENTS); tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_INCLUDE_STATEMENTS);
return PROCESS_CONTINUE;
} }
/* (non-Javadoc) /* (non-Javadoc)

View file

@ -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.ICFileType;
import org.eclipse.cdt.core.filetype.ICFileTypeConstants; import org.eclipse.cdt.core.filetype.ICFileTypeConstants;
import org.eclipse.cdt.core.model.CModelException; 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.ParserLanguage;
import org.eclipse.cdt.core.parser.ParserUtil; import org.eclipse.cdt.core.parser.ParserUtil;
import org.eclipse.cdt.core.parser.ast.IASTEnumerator; import org.eclipse.cdt.core.parser.ast.IASTEnumerator;
@ -948,6 +952,7 @@ public class DOMAST extends ViewPart {
} }
private class ASTHighlighterAction extends Action { private class ASTHighlighterAction extends Action {
private static final String A_PART_INSTANCEOF = "aPart instanceof "; //$NON-NLS-1$
IEditorPart aPart = null; IEditorPart aPart = null;
public ASTHighlighterAction(IEditorPart part) { public ASTHighlighterAction(IEditorPart part) {
@ -977,6 +982,9 @@ public class DOMAST extends ViewPart {
ISelection selection = viewer.getSelection(); ISelection selection = viewer.getSelection();
Object obj = ((IStructuredSelection) selection).getFirstElement(); Object obj = ((IStructuredSelection) selection).getFirstElement();
if (obj instanceof DOMASTNodeLeaf) { if (obj instanceof DOMASTNodeLeaf) {
if (((DOMASTNodeLeaf)obj).getNode() instanceof IASTTranslationUnit) // don't do anything for TU
return;
String filename = ((DOMASTNodeLeaf) obj).getFilename(); String filename = ((DOMASTNodeLeaf) obj).getFilename();
if (filename.equals(DOMASTNodeLeaf.BLANK_STRING)) if (filename.equals(DOMASTNodeLeaf.BLANK_STRING))
@ -993,9 +1001,12 @@ public class DOMAST extends ViewPart {
} }
} else { } else {
IPath path = new Path( filename ); IPath path = new Path( filename );
FileStorage storage = new FileStorage(null, path);
ICProject cproject = new CProject(null, file.getProject());
ITranslationUnit unit = CoreModel.getDefault().createTranslationUnitFrom(cproject, path);
if (unit != null)
try { try {
aPart = EditorUtility.openInEditor(storage); aPart = EditorUtility.openInEditor(unit);
} catch (PartInitException e) { } catch (PartInitException e) {
return; return;
} catch (CModelException e) { } catch (CModelException e) {
@ -1009,12 +1020,13 @@ public class DOMAST extends ViewPart {
((DOMASTNodeLeaf) obj).getLength()); ((DOMASTNodeLeaf) obj).getLength());
} }
else else
System.out.println( "aPart instanceof " + aPart.getClass().getName() ); System.out.println( A_PART_INSTANCEOF + aPart.getClass().getName() );
aPart.getSite().getPage().activate(aPart.getSite().getPage().findView(VIEW_ID)); aPart.getSite().getPage().activate(aPart.getSite().getPage().findView(VIEW_ID));
} }
} }
} }
private class DisplayDeclarationsAction extends DisplaySearchResultAction { private class DisplayDeclarationsAction extends DisplaySearchResultAction {

View file

@ -346,6 +346,9 @@ public class DOMASTNodeLeaf implements IAdaptable {
return null; return null;
} }
public IPropertyDescriptor[] getPropertyDescriptors() { 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]; IPropertyDescriptor[] descriptors = new IPropertyDescriptor[DEFAULT_DESCRIPTOR_SIZE];
if (node instanceof IASTName) { if (node instanceof IASTName) {

View file

@ -16,6 +16,7 @@ import java.util.Comparator;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement; 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.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
@ -24,12 +25,14 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
* @author dsteffle * @author dsteffle
*/ */
public class DOMASTNodeParent extends DOMASTNodeLeaf { 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 DOMASTNodeLeaf[] EMPTY_CHILDREN_ARRAY = new DOMASTNodeLeaf[0];
private static final int DEFAULT_NODE_CHAIN_SIZE = 4; private static final int DEFAULT_NODE_CHAIN_SIZE = 4;
private static final int DEFAULT_CHILDREN_SIZE = 4; private static final int DEFAULT_CHILDREN_SIZE = 4;
int index=0; int index=0;
private DOMASTNodeLeaf[] children; private DOMASTNodeLeaf[] children;
boolean cleanupedElements = false; boolean cleanupedElements = false;
private int indexFirstPreproStmnt=NO_PREPROCESSOR_STATMENT;
public int getStartSearch() { public int getStartSearch() {
return index; return index;
@ -45,6 +48,10 @@ public class DOMASTNodeParent extends DOMASTNodeLeaf {
children = new DOMASTNodeLeaf[DEFAULT_CHILDREN_SIZE]; children = new DOMASTNodeLeaf[DEFAULT_CHILDREN_SIZE];
} }
public void addChild(DOMASTNodeLeaf child) { public void addChild(DOMASTNodeLeaf child) {
if (child.getNode() instanceof IASTPreprocessorStatement && indexFirstPreproStmnt == NO_PREPROCESSOR_STATMENT) {
indexFirstPreproStmnt=index;
}
if (index==children.length) { if (index==children.length) {
children = (DOMASTNodeLeaf[])ArrayUtil.append(DOMASTNodeLeaf.class, children, child); children = (DOMASTNodeLeaf[])ArrayUtil.append(DOMASTNodeLeaf.class, children, child);
index++; index++;
@ -67,14 +74,21 @@ public class DOMASTNodeParent extends DOMASTNodeLeaf {
public DOMASTNodeLeaf[] getChildren(boolean cleanupElements) { public DOMASTNodeLeaf[] getChildren(boolean cleanupElements) {
if (cleanupElements) { if (cleanupElements) {
return getChildren(); return getChildren();
} else {
return children;
} }
return children;
} }
public DOMASTNodeLeaf [] getChildren() { public DOMASTNodeLeaf [] getChildren() {
// remove null children from the array (if not already done so) // remove null children from the array (if not already done so)
if (!cleanupedElements) { if (!cleanupedElements) {
cleanChildren();
}
return children;
}
public void cleanChildren() {
// remove null elements // remove null elements
children = (DOMASTNodeLeaf[])ArrayUtil.removeNulls(DOMASTNodeLeaf.class, children); children = (DOMASTNodeLeaf[])ArrayUtil.removeNulls(DOMASTNodeLeaf.class, children);
@ -94,19 +108,75 @@ public class DOMASTNodeParent extends DOMASTNodeLeaf {
// need to also clean up the children's children, to make sure all nulls are removed (prevent expansion sign when there isn't one) // 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; i<children.length; i++) { for(int i=0; i<children.length; i++) {
if (children[i] instanceof DOMASTNodeParent) { if (children[i] instanceof DOMASTNodeParent) {
((DOMASTNodeParent)children[i]).setChildren((DOMASTNodeLeaf[])ArrayUtil.removeNulls(DOMASTNodeLeaf.class, ((DOMASTNodeParent)children[i]).getChildren())); DOMASTNodeLeaf[] kids = ((DOMASTNodeParent)children[i]).children;
// remove null elements
kids = (DOMASTNodeLeaf[])ArrayUtil.removeNulls(DOMASTNodeLeaf.class, kids);
((DOMASTNodeParent)children[i]).setChildren(kids);
} }
} }
cleanupedElements = true; cleanupedElements = true;
} }
return children;
}
public boolean hasChildren() { public boolean hasChildren() {
return children.length>0; return children.length>0;
} }
/**
* 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. * Returns the DOMASTNodeParent whose IASTNode is the parent of the IASTNode.
* *