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:
parent
f9a0362d08
commit
81d46bfbf6
5 changed files with 253 additions and 142 deletions
|
@ -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;
|
||||||
|
@ -75,41 +74,55 @@ public class CPPPopulateASTViewAction extends CPPASTVisitor implements IPopulate
|
||||||
}
|
}
|
||||||
|
|
||||||
private int addRoot(IASTNode node) {
|
private int addRoot(IASTNode node) {
|
||||||
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 &&
|
return PROCESS_CONTINUE;
|
||||||
nodeLocations[0].getNodeLength() > 0))
|
|
||||||
return PROCESS_CONTINUE;
|
|
||||||
|
|
||||||
DOMASTNodeParent parent = root.findTreeParentForNode(node);
|
DOMASTNodeParent parent = null;
|
||||||
|
|
||||||
if (parent == null)
|
// if it's a preprocessor statement being merged then do a special search for parent (no search)
|
||||||
parent = root;
|
if (node instanceof IASTPreprocessorStatement) {
|
||||||
|
parent = root;
|
||||||
|
} else {
|
||||||
|
IASTNode tempParent = node.getParent();
|
||||||
|
if (tempParent instanceof IASTPreprocessorStatement) {
|
||||||
|
parent = root.findTreeParentForMergedNode(node);
|
||||||
|
} else {
|
||||||
|
parent = root.findTreeParentForNode(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DOMASTNodeParent tree = new DOMASTNodeParent(node);
|
if (parent == null)
|
||||||
parent.addChild(tree);
|
parent = root;
|
||||||
|
|
||||||
// set filter flags
|
createNode(parent, node);
|
||||||
if (node instanceof IASTProblemHolder || node instanceof IASTProblem) {
|
|
||||||
tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_PROBLEM);
|
|
||||||
|
|
||||||
if (node instanceof IASTProblemHolder)
|
return PROCESS_CONTINUE;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processDeclaration(org.eclipse.cdt.core.dom.ast.IASTDeclaration)
|
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processDeclaration(org.eclipse.cdt.core.dom.ast.IASTDeclaration)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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,37 +70,51 @@ 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 (parent == null)
|
// if it's a preprocessor statement being merged then do a special search for parent (no search)
|
||||||
parent = root;
|
if (node instanceof IASTPreprocessorStatement) {
|
||||||
|
parent = root;
|
||||||
|
} else {
|
||||||
|
IASTNode tempParent = node.getParent();
|
||||||
|
if (tempParent instanceof IASTPreprocessorStatement) {
|
||||||
|
parent = root.findTreeParentForMergedNode(node);
|
||||||
|
} else {
|
||||||
|
parent = root.findTreeParentForNode(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DOMASTNodeParent tree = new DOMASTNodeParent(node);
|
if (parent == null)
|
||||||
parent.addChild(tree);
|
parent = root;
|
||||||
|
|
||||||
// set filter flags
|
createNode(parent, node);
|
||||||
if (node instanceof IASTProblemHolder || node instanceof IASTProblem) {
|
|
||||||
tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_PROBLEM);
|
|
||||||
|
|
||||||
if (node instanceof IASTProblemHolder)
|
return PROCESS_CONTINUE;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processDeclaration(org.eclipse.cdt.core.dom.ast.IASTDeclaration)
|
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processDeclaration(org.eclipse.cdt.core.dom.ast.IASTDeclaration)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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) {
|
||||||
|
@ -974,47 +979,54 @@ public class DOMAST extends ViewPart {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
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) {
|
||||||
String filename = ((DOMASTNodeLeaf) obj).getFilename();
|
if (((DOMASTNodeLeaf)obj).getNode() instanceof IASTTranslationUnit) // don't do anything for TU
|
||||||
|
return;
|
||||||
|
|
||||||
if (filename.equals(DOMASTNodeLeaf.BLANK_STRING))
|
String filename = ((DOMASTNodeLeaf) obj).getFilename();
|
||||||
return;
|
|
||||||
|
|
||||||
IResource r = ParserUtil.getResourceForFilename(filename);
|
if (filename.equals(DOMASTNodeLeaf.BLANK_STRING))
|
||||||
if (r != null) {
|
return;
|
||||||
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 )
|
IResource r = ParserUtil.getResourceForFilename(filename);
|
||||||
{
|
if (r != null) {
|
||||||
((AbstractTextEditor) aPart).selectAndReveal(((DOMASTNodeLeaf) obj).getOffset(),
|
try {
|
||||||
((DOMASTNodeLeaf) obj).getLength());
|
aPart = EditorUtility.openInEditor(r);
|
||||||
}
|
} catch (PartInitException pie) {
|
||||||
else
|
return;
|
||||||
System.out.println( "aPart instanceof " + aPart.getClass().getName() );
|
} catch (CModelException e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
IPath path = new Path( filename );
|
||||||
|
|
||||||
aPart.getSite().getPage().activate(aPart.getSite().getPage().findView(VIEW_ID));
|
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 {
|
private class DisplayDeclarationsAction extends DisplaySearchResultAction {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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++;
|
||||||
|
@ -64,49 +71,112 @@ public class DOMASTNodeParent extends DOMASTNodeLeaf {
|
||||||
child.setParent(null);
|
child.setParent(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
// remove null elements
|
cleanChildren();
|
||||||
children = (DOMASTNodeLeaf[])ArrayUtil.removeNulls(DOMASTNodeLeaf.class, children);
|
}
|
||||||
|
|
||||||
// sort the elements
|
return children;
|
||||||
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; i<children.length; i++) {
|
|
||||||
if (children[i] instanceof DOMASTNodeParent) {
|
|
||||||
((DOMASTNodeParent)children[i]).setChildren((DOMASTNodeLeaf[])ArrayUtil.removeNulls(DOMASTNodeLeaf.class, ((DOMASTNodeParent)children[i]).getChildren()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanupedElements = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return children;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void cleanChildren() {
|
||||||
|
// 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; i<children.length; i++) {
|
||||||
|
if (children[i] instanceof DOMASTNodeParent) {
|
||||||
|
DOMASTNodeLeaf[] kids = ((DOMASTNodeParent)children[i]).children;
|
||||||
|
// remove null elements
|
||||||
|
kids = (DOMASTNodeLeaf[])ArrayUtil.removeNulls(DOMASTNodeLeaf.class, kids);
|
||||||
|
((DOMASTNodeParent)children[i]).setChildren(kids);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanupedElements = true;
|
||||||
|
}
|
||||||
|
|
||||||
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.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Add table
Reference in a new issue