1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-13 19:25:38 +02:00

bug 94989 - ui.tests - selecting nodes in DOM AST View

This commit is contained in:
Andrew Niefer 2005-07-25 18:41:30 +00:00
parent 2cfafe2975
commit 0e56897a3f
5 changed files with 492 additions and 342 deletions

View file

@ -48,7 +48,6 @@ import org.eclipse.core.runtime.IProgressMonitor;
*/
public class CPPPopulateASTViewAction extends CPPASTVisitor implements IPopulateDOMASTAction {
private static final int INITIAL_PROBLEM_SIZE = 4;
private static final int INITIAL_INCLUDE_STATEMENT_SIZE = 8;
{
shouldVisitNames = true;
shouldVisitDeclarations = true;
@ -73,14 +72,28 @@ public class CPPPopulateASTViewAction extends CPPASTVisitor implements IPopulate
this.monitor = monitor;
}
private int addRoot(IASTNode node) {
if (monitor != null && monitor.isCanceled()) return PROCESS_ABORT;
if (node == null) return PROCESS_CONTINUE;
private class DOMASTNodeLeafContinue extends DOMASTNodeLeaf {
public DOMASTNodeLeafContinue(IASTNode node) {
super(node);
}
}
/**
* return null if the algorithm should stop (monitor was cancelled)
* return DOMASTNodeLeafContinue if the algorithm should continue but no valid DOMASTNodeLeaf was added (i.e. node was null
* return the DOMASTNodeLeaf added to the DOM AST View's model otherwise
*
* @param node
* @return
*/
private DOMASTNodeLeaf addRoot(IASTNode node) {
if (monitor != null && monitor.isCanceled()) return null;
if (node == null) return new DOMASTNodeLeafContinue(null);
// 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;
return new DOMASTNodeLeafContinue(null);
DOMASTNodeParent parent = null;
@ -99,12 +112,10 @@ public class CPPPopulateASTViewAction extends CPPASTVisitor implements IPopulate
if (parent == null)
parent = root;
createNode(parent, node);
return PROCESS_CONTINUE;
return createNode(parent, node);
}
private void createNode(DOMASTNodeParent parent, IASTNode node) {
private DOMASTNodeLeaf createNode(DOMASTNodeParent parent, IASTNode node) {
DOMASTNodeParent tree = new DOMASTNodeParent(node);
parent.addChild(tree);
@ -121,20 +132,28 @@ public class CPPPopulateASTViewAction extends CPPASTVisitor implements IPopulate
tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_PREPROCESSOR);
if (node instanceof IASTPreprocessorIncludeStatement)
tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_INCLUDE_STATEMENTS);
return tree;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processDeclaration(org.eclipse.cdt.core.dom.ast.IASTDeclaration)
*/
public int visit(IASTDeclaration declaration) {
return addRoot(declaration);
DOMASTNodeLeaf temp = addRoot(declaration);
if (temp == null)
return PROCESS_ABORT;
else if (temp instanceof DOMASTNodeLeafContinue)
return PROCESS_CONTINUE;
else
return PROCESS_CONTINUE;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processDeclarator(org.eclipse.cdt.core.dom.ast.IASTDeclarator)
*/
public int visit(IASTDeclarator declarator) {
int ret = addRoot(declarator);
DOMASTNodeLeaf temp = addRoot(declarator);
IASTPointerOperator[] ops = declarator.getPointerOperators();
for(int i=0; i<ops.length; i++)
@ -160,50 +179,94 @@ public class CPPPopulateASTViewAction extends CPPASTVisitor implements IPopulate
}
}
return ret;
if (temp == null)
return PROCESS_ABORT;
else if (temp instanceof DOMASTNodeLeafContinue)
return PROCESS_CONTINUE;
else
return PROCESS_CONTINUE;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processBaseSpecifier(org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier)
*/
public int visit(ICPPASTBaseSpecifier specifier) {
return addRoot(specifier);
DOMASTNodeLeaf temp = addRoot(specifier);
if (temp == null)
return PROCESS_ABORT;
else if (temp instanceof DOMASTNodeLeafContinue)
return PROCESS_CONTINUE;
else
return PROCESS_CONTINUE;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processDeclSpecifier(org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier)
*/
public int visit(IASTDeclSpecifier declSpec) {
return addRoot(declSpec);
DOMASTNodeLeaf temp = addRoot(declSpec);
if (temp == null)
return PROCESS_ABORT;
else if (temp instanceof DOMASTNodeLeafContinue)
return PROCESS_CONTINUE;
else
return PROCESS_CONTINUE;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processEnumerator(org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator)
*/
public int visit(IASTEnumerator enumerator) {
return addRoot(enumerator);
DOMASTNodeLeaf temp = addRoot(enumerator);
if (temp == null)
return PROCESS_ABORT;
else if (temp instanceof DOMASTNodeLeafContinue)
return PROCESS_CONTINUE;
else
return PROCESS_CONTINUE;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processExpression(org.eclipse.cdt.core.dom.ast.IASTExpression)
*/
public int visit(IASTExpression expression) {
return addRoot(expression);
DOMASTNodeLeaf temp = addRoot(expression);
if (temp == null)
return PROCESS_ABORT;
else if (temp instanceof DOMASTNodeLeafContinue)
return PROCESS_CONTINUE;
else
return PROCESS_CONTINUE;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processInitializer(org.eclipse.cdt.core.dom.ast.IASTInitializer)
*/
public int visit(IASTInitializer initializer) {
return addRoot(initializer);
DOMASTNodeLeaf temp = addRoot(initializer);
if (temp == null)
return PROCESS_ABORT;
else if (temp instanceof DOMASTNodeLeafContinue)
return PROCESS_CONTINUE;
else
return PROCESS_CONTINUE;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processName(org.eclipse.cdt.core.dom.ast.IASTName)
*/
public int visit(IASTName name) {
DOMASTNodeLeaf temp = null;
if (name.toString() != null)
return addRoot(name);
temp = addRoot(name);
else
return PROCESS_CONTINUE;
if (temp == null)
return PROCESS_ABORT;
else if (temp instanceof DOMASTNodeLeafContinue)
return PROCESS_CONTINUE;
else
return PROCESS_CONTINUE;
}
@ -211,7 +274,13 @@ public class CPPPopulateASTViewAction extends CPPASTVisitor implements IPopulate
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processNamespace(org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition)
*/
public int visit(ICPPASTNamespaceDefinition namespace) {
return addRoot(namespace);
DOMASTNodeLeaf temp = addRoot(namespace);
if (temp == null)
return PROCESS_ABORT;
else if (temp instanceof DOMASTNodeLeafContinue)
return PROCESS_CONTINUE;
else
return PROCESS_CONTINUE;
}
/* (non-Javadoc)
@ -219,37 +288,60 @@ public class CPPPopulateASTViewAction extends CPPASTVisitor implements IPopulate
*/
public int visit(
IASTParameterDeclaration parameterDeclaration) {
return addRoot(parameterDeclaration);
DOMASTNodeLeaf temp = addRoot(parameterDeclaration);
if (temp == null)
return PROCESS_ABORT;
else if (temp instanceof DOMASTNodeLeafContinue)
return PROCESS_CONTINUE;
else
return PROCESS_CONTINUE;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processStatement(org.eclipse.cdt.core.dom.ast.IASTStatement)
*/
public int visit(IASTStatement statement) {
return addRoot(statement);
DOMASTNodeLeaf temp = addRoot(statement);
if (temp == null)
return PROCESS_ABORT;
else if (temp instanceof DOMASTNodeLeafContinue)
return PROCESS_CONTINUE;
else
return PROCESS_CONTINUE;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processTypeId(org.eclipse.cdt.core.dom.ast.IASTTypeId)
*/
public int visit(IASTTypeId typeId) {
return addRoot(typeId);
DOMASTNodeLeaf temp = addRoot(typeId);
if (temp == null)
return PROCESS_ABORT;
else if (temp instanceof DOMASTNodeLeafContinue)
return PROCESS_CONTINUE;
else
return PROCESS_CONTINUE;
}
private void mergeNode(ASTNode node) {
addRoot(node);
private DOMASTNodeLeaf mergeNode(ASTNode node) {
DOMASTNodeLeaf leaf = addRoot(node);
if (node instanceof IASTPreprocessorMacroDefinition)
addRoot(((IASTPreprocessorMacroDefinition)node).getName());
return leaf;
}
public void mergePreprocessorStatements(IASTPreprocessorStatement[] statements) {
public DOMASTNodeLeaf[] mergePreprocessorStatements(IASTPreprocessorStatement[] statements) {
DOMASTNodeLeaf[] leaves = new DOMASTNodeLeaf[statements.length];
for(int i=0; i<statements.length; i++) {
if (monitor != null && monitor.isCanceled()) return;
if (monitor != null && monitor.isCanceled()) return leaves;
if (statements[i] instanceof ASTNode)
mergeNode((ASTNode)statements[i]);
leaves[i] = mergeNode((ASTNode)statements[i]);
}
return leaves;
}
public void mergePreprocessorProblems(IASTProblem[] problems) {
@ -265,45 +357,26 @@ public class CPPPopulateASTViewAction extends CPPASTVisitor implements IPopulate
return root;
}
public void groupIncludes(IASTPreprocessorStatement[] statements) {
// get all of the includes from the preprocessor statements (need the object since .equals isn't implemented)
IASTPreprocessorIncludeStatement[] includes = new IASTPreprocessorIncludeStatement[INITIAL_INCLUDE_STATEMENT_SIZE];
int index = 0;
for(int i=0; i<statements.length; i++) {
if (monitor != null && monitor.isCanceled()) return;
if (statements[i] instanceof IASTPreprocessorIncludeStatement) {
if (index == includes.length) {
includes = (IASTPreprocessorIncludeStatement[])ArrayUtil.append(IASTPreprocessorIncludeStatement.class, includes, statements[i]);
index++;
} else {
includes[index++] = (IASTPreprocessorIncludeStatement)statements[i];
}
}
}
// get the tree model elements corresponding to the includes
DOMASTNodeParent[] treeIncludes = new DOMASTNodeParent[index];
for (int i=0; i<treeIncludes.length; i++) {
if (monitor != null && monitor.isCanceled()) return;
treeIncludes[i] = root.findTreeObject(includes[i], false);
}
public void groupIncludes(DOMASTNodeLeaf[] treeIncludes) {
// loop through the includes and make sure that all of the nodes
// that are children of the TU are in the proper include (based on offset)
DOMASTNodeLeaf child = null;
outerLoop: for (int i=treeIncludes.length-1; i>=0; i--) {
outerLoop: for (int i=treeIncludes.length - 1; i >= 0; i-- ) {
if (treeIncludes[i] == null) continue;
for(int j=root.getChildren(false).length-1; j>=0; j--) {
if (monitor != null && monitor.isCanceled()) return;
IASTNode node = null;
for(int j=0; j < root.getChildren(false).length; j++) {
// if (monitor != null && monitor.isCanceled()) return; // this causes a deadlock when checked here
child = root.getChildren(false)[j];
node = treeIncludes[i].getNode();
if (child != null && treeIncludes[i] != child &&
includes[i] instanceof ASTInclusionStatement &&
((ASTNode)child.getNode()).getOffset() >= ((ASTInclusionStatement)includes[i]).startOffset &&
((ASTNode)child.getNode()).getOffset() <= ((ASTInclusionStatement)includes[i]).endOffset) {
node instanceof ASTInclusionStatement &&
((ASTNode)child.getNode()).getOffset() >= ((ASTInclusionStatement)node).startOffset &&
((ASTNode)child.getNode()).getOffset() <= ((ASTInclusionStatement)node).endOffset)
{
root.removeChild(child);
treeIncludes[i].addChild(child);
((DOMASTNodeParent)treeIncludes[i]).addChild(child);
}
}
}

View file

@ -42,7 +42,6 @@ import org.eclipse.core.runtime.IProgressMonitor;
*/
public class CPopulateASTViewAction extends CASTVisitor implements IPopulateDOMASTAction {
private static final int INITIAL_PROBLEM_SIZE = 4;
private static final int INITIAL_INCLUDE_STATEMENT_SIZE = 8;
{
shouldVisitNames = true;
shouldVisitDeclarations = true;
@ -66,13 +65,27 @@ public class CPopulateASTViewAction extends CASTVisitor implements IPopulateDOMA
this.monitor = monitor;
}
private int addRoot(IASTNode node) {
if (monitor != null && monitor.isCanceled()) return PROCESS_ABORT;
if (node == null) return PROCESS_CONTINUE;
private class DOMASTNodeLeafContinue extends DOMASTNodeLeaf {
public DOMASTNodeLeafContinue(IASTNode node) {
super(node);
}
}
/**
* return null if the algorithm should stop (monitor was cancelled)
* return DOMASTNodeLeafContinue if the algorithm should continue but no valid DOMASTNodeLeaf was added (i.e. node was null
* return the DOMASTNodeLeaf added to the DOM AST View's model otherwise
*
* @param node
* @return
*/
private DOMASTNodeLeaf addRoot(IASTNode node) {
if (monitor != null && monitor.isCanceled()) return null;
if (node == null) return new DOMASTNodeLeafContinue(null);
// only do length check for ASTNode (getNodeLocations on PreprocessorStatements is very expensive)
if (node instanceof ASTNode && ((ASTNode)node).getLength() <= 0)
return PROCESS_CONTINUE;
return new DOMASTNodeLeafContinue(null);
DOMASTNodeParent parent = null;
@ -91,12 +104,10 @@ public class CPopulateASTViewAction extends CASTVisitor implements IPopulateDOMA
if (parent == null)
parent = root;
createNode(parent, node);
return PROCESS_CONTINUE;
return createNode(parent, node);
}
private void createNode(DOMASTNodeParent parent, IASTNode node) {
private DOMASTNodeLeaf createNode(DOMASTNodeParent parent, IASTNode node) {
DOMASTNodeParent tree = new DOMASTNodeParent(node);
parent.addChild(tree);
@ -113,20 +124,28 @@ public class CPopulateASTViewAction extends CASTVisitor implements IPopulateDOMA
tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_PREPROCESSOR);
if (node instanceof IASTPreprocessorIncludeStatement)
tree.setFiltersFlag(DOMASTNodeLeaf.FLAG_INCLUDE_STATEMENTS);
return tree;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processDeclaration(org.eclipse.cdt.core.dom.ast.IASTDeclaration)
*/
public int visit(IASTDeclaration declaration) {
return addRoot(declaration);
DOMASTNodeLeaf temp = addRoot(declaration);
if (temp == null)
return PROCESS_ABORT;
else if (temp instanceof DOMASTNodeLeafContinue)
return PROCESS_CONTINUE;
else
return PROCESS_CONTINUE;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processDeclarator(org.eclipse.cdt.core.dom.ast.IASTDeclarator)
*/
public int visit(IASTDeclarator declarator) {
int ret = addRoot(declarator);
DOMASTNodeLeaf temp = addRoot(declarator);
IASTPointerOperator[] ops = declarator.getPointerOperators();
for(int i=0; i<ops.length; i++)
@ -138,50 +157,93 @@ public class CPopulateASTViewAction extends CASTVisitor implements IPopulateDOMA
addRoot(mods[i]);
}
return ret;
if (temp == null)
return PROCESS_ABORT;
else if (temp instanceof DOMASTNodeLeafContinue)
return PROCESS_CONTINUE;
else
return PROCESS_CONTINUE;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processDesignator(org.eclipse.cdt.core.dom.ast.c.ICASTDesignator)
*/
public int visit(ICASTDesignator designator) {
return addRoot(designator);
DOMASTNodeLeaf temp = addRoot(designator);
if (temp == null)
return PROCESS_ABORT;
else if (temp instanceof DOMASTNodeLeafContinue)
return PROCESS_CONTINUE;
else
return PROCESS_CONTINUE;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processDeclSpecifier(org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier)
*/
public int visit(IASTDeclSpecifier declSpec) {
return addRoot(declSpec);
DOMASTNodeLeaf temp = addRoot(declSpec);
if (temp == null)
return PROCESS_ABORT;
else if (temp instanceof DOMASTNodeLeafContinue)
return PROCESS_CONTINUE;
else
return PROCESS_CONTINUE;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processEnumerator(org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator)
*/
public int visit(IASTEnumerator enumerator) {
return addRoot(enumerator);
DOMASTNodeLeaf temp = addRoot(enumerator);
if (temp == null)
return PROCESS_ABORT;
else if (temp instanceof DOMASTNodeLeafContinue)
return PROCESS_CONTINUE;
else
return PROCESS_CONTINUE;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processExpression(org.eclipse.cdt.core.dom.ast.IASTExpression)
*/
public int visit(IASTExpression expression) {
return addRoot(expression);
DOMASTNodeLeaf temp = addRoot(expression);
if (temp == null)
return PROCESS_ABORT;
else if (temp instanceof DOMASTNodeLeafContinue)
return PROCESS_CONTINUE;
else
return PROCESS_CONTINUE;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processInitializer(org.eclipse.cdt.core.dom.ast.IASTInitializer)
*/
public int visit(IASTInitializer initializer) {
return addRoot(initializer);
DOMASTNodeLeaf temp = addRoot(initializer);
if (temp == null)
return PROCESS_ABORT;
else if (temp instanceof DOMASTNodeLeafContinue)
return PROCESS_CONTINUE;
else
return PROCESS_CONTINUE;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processName(org.eclipse.cdt.core.dom.ast.IASTName)
*/
public int visit(IASTName name) {
DOMASTNodeLeaf temp = null;
if ( name.toString() != null )
return addRoot(name);
temp = addRoot(name);
else
return PROCESS_CONTINUE;
if (temp == null)
return PROCESS_ABORT;
else if (temp instanceof DOMASTNodeLeafContinue)
return PROCESS_CONTINUE;
else
return PROCESS_CONTINUE;
}
@ -190,37 +252,60 @@ public class CPopulateASTViewAction extends CASTVisitor implements IPopulateDOMA
*/
public int visit(
IASTParameterDeclaration parameterDeclaration) {
return addRoot(parameterDeclaration);
DOMASTNodeLeaf temp = addRoot(parameterDeclaration);
if (temp == null)
return PROCESS_ABORT;
else if (temp instanceof DOMASTNodeLeafContinue)
return PROCESS_CONTINUE;
else
return PROCESS_CONTINUE;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processStatement(org.eclipse.cdt.core.dom.ast.IASTStatement)
*/
public int visit(IASTStatement statement) {
return addRoot(statement);
DOMASTNodeLeaf temp = addRoot(statement);
if (temp == null)
return PROCESS_ABORT;
else if (temp instanceof DOMASTNodeLeafContinue)
return PROCESS_CONTINUE;
else
return PROCESS_CONTINUE;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processTypeId(org.eclipse.cdt.core.dom.ast.IASTTypeId)
*/
public int visit(IASTTypeId typeId) {
return addRoot(typeId);
DOMASTNodeLeaf temp = addRoot(typeId);
if (temp == null)
return PROCESS_ABORT;
else if (temp instanceof DOMASTNodeLeafContinue)
return PROCESS_CONTINUE;
else
return PROCESS_CONTINUE;
}
private void mergeNode(ASTNode node) {
addRoot(node);
private DOMASTNodeLeaf mergeNode(ASTNode node) {
DOMASTNodeLeaf temp = addRoot(node);
if (node instanceof IASTPreprocessorMacroDefinition )
addRoot(((IASTPreprocessorMacroDefinition)node).getName());
return temp;
}
public void mergePreprocessorStatements(IASTPreprocessorStatement[] statements) {
public DOMASTNodeLeaf[] mergePreprocessorStatements(IASTPreprocessorStatement[] statements) {
DOMASTNodeLeaf[] leaves = new DOMASTNodeLeaf[statements.length];
for(int i=0; i<statements.length; i++) {
if (monitor != null && monitor.isCanceled()) return;
if (monitor != null && monitor.isCanceled()) return leaves;
if (statements[i] instanceof ASTNode)
mergeNode((ASTNode)statements[i]);
leaves[i] = mergeNode((ASTNode)statements[i]);
}
return leaves;
}
public void mergePreprocessorProblems(IASTProblem[] problems) {
@ -236,46 +321,26 @@ public class CPopulateASTViewAction extends CASTVisitor implements IPopulateDOMA
return root;
}
public void groupIncludes(IASTPreprocessorStatement[] statements) {
// get all of the includes from the preprocessor statements (need the object since .equals isn't implemented)
IASTPreprocessorIncludeStatement[] includes = new IASTPreprocessorIncludeStatement[INITIAL_INCLUDE_STATEMENT_SIZE];
int index = 0;
for(int i=0; i<statements.length; i++) {
if (monitor != null && monitor.isCanceled()) return;
if (statements[i] instanceof IASTPreprocessorIncludeStatement) {
if (index == includes.length) {
includes = (IASTPreprocessorIncludeStatement[])ArrayUtil.append(IASTPreprocessorIncludeStatement.class, includes, statements[i]);
index++;
} else {
includes[index++] = (IASTPreprocessorIncludeStatement)statements[i];
}
}
}
// get the tree model elements corresponding to the includes
DOMASTNodeParent[] treeIncludes = new DOMASTNodeParent[index];
for (int i=0; i<treeIncludes.length; i++) {
if (monitor != null && monitor.isCanceled()) return;
treeIncludes[i] = root.findTreeObject(includes[i], false);
}
public void groupIncludes(DOMASTNodeLeaf[] treeIncludes) {
// loop through the includes and make sure that all of the nodes
// that are children of the TU are in the proper include (based on offset)
DOMASTNodeLeaf child = null;
outerLoop: for (int i=treeIncludes.length-1; i>=0; i--) {
if (treeIncludes[i] == null) continue;
for(int j=root.getChildren(false).length-1; j>=0; j--) {
if (monitor != null && monitor.isCanceled()) return;
IASTNode node = null;
for(int j=0; j < root.getChildren(false).length; j++) {
// if (monitor != null && monitor.isCanceled()) return; // this causes a deadlock when checked here
child = root.getChildren(false)[j];
node = treeIncludes[i].getNode();
if (child != null &&
treeIncludes[i] != child &&
includes[i] instanceof ASTInclusionStatement &&
((ASTNode)child.getNode()).getOffset() >= ((ASTInclusionStatement)includes[i]).startOffset &&
((ASTNode)child.getNode()).getOffset() <= ((ASTInclusionStatement)includes[i]).endOffset) {
node instanceof ASTInclusionStatement &&
((ASTNode)child.getNode()).getOffset() >= ((ASTInclusionStatement)node).startOffset &&
((ASTNode)child.getNode()).getOffset() <= ((ASTInclusionStatement)node).endOffset) {
root.removeChild(child);
treeIncludes[i].addChild(child);
((DOMASTNodeParent)treeIncludes[i]).addChild(child);
}
}
}

View file

@ -404,7 +404,7 @@ public class DOMAST extends ViewPart {
monitor.subTask(MERGING_ + statements.length + _PREPROCESSOR_STATEMENTS_);
start=System.currentTimeMillis();
// merge preprocessor statements to the tree
action.mergePreprocessorStatements(statements);
DOMASTNodeLeaf[] includeStatements = action.mergePreprocessorStatements(statements);
monitor.worked(2);
System.out.println(DOM_AST_VIEW_DONE + MERGING_ + statements.length + _PREPROCESSOR_STATEMENTS_ + COLON_SPACE + (System.currentTimeMillis()- start) );
@ -426,7 +426,7 @@ public class DOMAST extends ViewPart {
monitor.subTask(GROUPING_AST);
start=System.currentTimeMillis();
// group #includes
action.groupIncludes(statements);
action.groupIncludes(includeStatements);
monitor.worked(30);
System.out.println(DOM_AST_VIEW_DONE + GROUPING_AST + COLON_SPACE + (System.currentTimeMillis()- start) );

View file

@ -10,12 +10,10 @@
*******************************************************************************/
package org.eclipse.cdt.ui.tests.DOMAST;
import java.util.Arrays;
import java.util.Comparator;
import java.lang.reflect.Array;
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;
@ -88,22 +86,80 @@ public class DOMASTNodeParent extends DOMASTNodeLeaf {
return children;
}
/**
* Inserts obj into the array at position pos and if this is not possible (due to a bad offset)
* then the obj is just appended to the end of the array.
*
* @param c
* @param array
* @param obj
* @param pos
* @return
*/
public Object[] insert(Class c, Object[] array, Object obj, int pos) {
if (pos < 0 || pos >= array.length) {
return ArrayUtil.append(c, array, obj);
}
Object[] temp = (Object[]) Array.newInstance( c, array.length + 1 );
if (pos > 0) {
System.arraycopy( array, 0, temp, 0, pos );
temp[pos] = obj;
System.arraycopy( array, pos, temp, pos + 1, array.length - pos );
} else {
temp[0] = obj;
System.arraycopy( array, 0, temp, 1, array.length );
}
return temp;
}
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();
//if (indexFirstPreproStmnt >= 0) { // TODO Devin what if it's ALL preprocessor statements ?
int firstOffset=0;
int firstLength=0;
int checkOffset=0;
int checkLength=0;
boolean moved=false;
for (int j=0, i=0; j < children.length && children[j] != null; j++) {
if( !(children[j].getNode() instanceof IASTPreprocessorStatement) )
continue;
while(true) {
if (i==j) break; // don't need to check itself or anything after it
checkOffset = ((ASTNode)children[j].getNode()).getOffset();
checkLength = ((ASTNode)children[j].getNode()).getLength();
firstOffset = ((ASTNode)children[i].getNode()).getOffset();
firstLength = ((ASTNode)children[i].getNode()).getLength();
// if the checking element comes before the first element then move the checking element before the first element
if (checkOffset < firstOffset && checkOffset + checkLength < firstOffset + firstLength) {
DOMASTNodeLeaf temp = children[j];
System.arraycopy( children, i, children, i + 1, j - i );
children[i] = temp;
break;
}
return 0;
// if the checking element is within the bounds of the first element then it must be a child of that element
if (checkOffset > firstOffset && checkOffset + checkLength < firstOffset + firstLength) {
DOMASTNodeLeaf temp = children[j];
if( j + 1 < children.length )
System.arraycopy( children, j + 1, children, j, children.length - j - 1 );
children[ children.length - 1 ] = null;
((DOMASTNodeParent)children[i]).addChild(temp);
j--;
break;
}
});
i++;
}
}
// }
children = (DOMASTNodeLeaf[])ArrayUtil.removeNulls(DOMASTNodeLeaf.class, children);
// 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++) {
@ -157,7 +213,7 @@ public class DOMASTNodeParent extends DOMASTNodeLeaf {
if (nodeChain[i] != null) {
parentToFind = nodeChain[i];
for(; j>=indexFirstPreproStmnt; j--) {
for(; j>=0; j--) {
if (childrenToSearch[j] instanceof DOMASTNodeParent) {
if ( childrenToSearch[j].getNode() == node.getParent() ) {
return (DOMASTNodeParent)childrenToSearch[j];
@ -270,47 +326,6 @@ public class DOMASTNodeParent extends DOMASTNodeLeaf {
if (equalNodes(node, this.getNode(), useOffset)) {
return this;
}
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];
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(), 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;
}
}
}
}
}
}
} else {
if( children.length == 0 )
return null;
if( !cleanupedElements ){
@ -343,9 +358,6 @@ public class DOMASTNodeParent extends DOMASTNodeLeaf {
}
}
return null; // nothing found
}
private boolean equalNodes(IASTNode node1, IASTNode node2, boolean useOffset) {
if (useOffset) {
if (node1 instanceof ASTNode && node2 instanceof ASTNode) {

View file

@ -18,7 +18,7 @@ import org.eclipse.cdt.core.dom.ast.IASTProblem;
*/
public interface IPopulateDOMASTAction {
public DOMASTNodeParent getTree();
public void mergePreprocessorStatements(IASTPreprocessorStatement[] statements);
public DOMASTNodeLeaf[] mergePreprocessorStatements(IASTPreprocessorStatement[] statements);
public void mergePreprocessorProblems(IASTProblem[] problems);
public void groupIncludes(IASTPreprocessorStatement[] statements);
public void groupIncludes(DOMASTNodeLeaf[] statements);
}