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:
parent
2cfafe2975
commit
0e56897a3f
5 changed files with 492 additions and 342 deletions
|
@ -48,7 +48,6 @@ import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
*/
|
*/
|
||||||
public class CPPPopulateASTViewAction extends CPPASTVisitor implements IPopulateDOMASTAction {
|
public class CPPPopulateASTViewAction extends CPPASTVisitor implements IPopulateDOMASTAction {
|
||||||
private static final int INITIAL_PROBLEM_SIZE = 4;
|
private static final int INITIAL_PROBLEM_SIZE = 4;
|
||||||
private static final int INITIAL_INCLUDE_STATEMENT_SIZE = 8;
|
|
||||||
{
|
{
|
||||||
shouldVisitNames = true;
|
shouldVisitNames = true;
|
||||||
shouldVisitDeclarations = true;
|
shouldVisitDeclarations = true;
|
||||||
|
@ -73,14 +72,28 @@ public class CPPPopulateASTViewAction extends CPPASTVisitor implements IPopulate
|
||||||
this.monitor = monitor;
|
this.monitor = monitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int addRoot(IASTNode node) {
|
private class DOMASTNodeLeafContinue extends DOMASTNodeLeaf {
|
||||||
if (monitor != null && monitor.isCanceled()) return PROCESS_ABORT;
|
public DOMASTNodeLeafContinue(IASTNode node) {
|
||||||
if (node == null) return PROCESS_CONTINUE;
|
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)
|
// only do length check for ASTNode (getNodeLocations on PreprocessorStatements is very expensive)
|
||||||
if (!(node instanceof ICPPASTLinkageSpecification) &&
|
if (!(node instanceof ICPPASTLinkageSpecification) &&
|
||||||
node instanceof ASTNode && ((ASTNode)node).getLength() <= 0)
|
node instanceof ASTNode && ((ASTNode)node).getLength() <= 0)
|
||||||
return PROCESS_CONTINUE;
|
return new DOMASTNodeLeafContinue(null);
|
||||||
|
|
||||||
DOMASTNodeParent parent = null;
|
DOMASTNodeParent parent = null;
|
||||||
|
|
||||||
|
@ -99,12 +112,10 @@ public class CPPPopulateASTViewAction extends CPPASTVisitor implements IPopulate
|
||||||
if (parent == null)
|
if (parent == null)
|
||||||
parent = root;
|
parent = root;
|
||||||
|
|
||||||
createNode(parent, node);
|
return createNode(parent, node);
|
||||||
|
|
||||||
return PROCESS_CONTINUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createNode(DOMASTNodeParent parent, IASTNode node) {
|
private DOMASTNodeLeaf createNode(DOMASTNodeParent parent, IASTNode node) {
|
||||||
DOMASTNodeParent tree = new DOMASTNodeParent(node);
|
DOMASTNodeParent tree = new DOMASTNodeParent(node);
|
||||||
parent.addChild(tree);
|
parent.addChild(tree);
|
||||||
|
|
||||||
|
@ -121,20 +132,28 @@ 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 tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (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)
|
||||||
*/
|
*/
|
||||||
public int visit(IASTDeclaration declaration) {
|
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)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processDeclarator(org.eclipse.cdt.core.dom.ast.IASTDeclarator)
|
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processDeclarator(org.eclipse.cdt.core.dom.ast.IASTDeclarator)
|
||||||
*/
|
*/
|
||||||
public int visit(IASTDeclarator declarator) {
|
public int visit(IASTDeclarator declarator) {
|
||||||
int ret = addRoot(declarator);
|
DOMASTNodeLeaf temp = addRoot(declarator);
|
||||||
|
|
||||||
IASTPointerOperator[] ops = declarator.getPointerOperators();
|
IASTPointerOperator[] ops = declarator.getPointerOperators();
|
||||||
for(int i=0; i<ops.length; i++)
|
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)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processBaseSpecifier(org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier)
|
* @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) {
|
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)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processDeclSpecifier(org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier)
|
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processDeclSpecifier(org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier)
|
||||||
*/
|
*/
|
||||||
public int visit(IASTDeclSpecifier declSpec) {
|
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)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processEnumerator(org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator)
|
* @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) {
|
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)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processExpression(org.eclipse.cdt.core.dom.ast.IASTExpression)
|
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processExpression(org.eclipse.cdt.core.dom.ast.IASTExpression)
|
||||||
*/
|
*/
|
||||||
public int visit(IASTExpression expression) {
|
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)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processInitializer(org.eclipse.cdt.core.dom.ast.IASTInitializer)
|
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processInitializer(org.eclipse.cdt.core.dom.ast.IASTInitializer)
|
||||||
*/
|
*/
|
||||||
public int visit(IASTInitializer initializer) {
|
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)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processName(org.eclipse.cdt.core.dom.ast.IASTName)
|
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processName(org.eclipse.cdt.core.dom.ast.IASTName)
|
||||||
*/
|
*/
|
||||||
public int visit(IASTName name) {
|
public int visit(IASTName name) {
|
||||||
|
DOMASTNodeLeaf temp = null;
|
||||||
if (name.toString() != 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;
|
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)
|
* @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) {
|
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)
|
/* (non-Javadoc)
|
||||||
|
@ -219,37 +288,60 @@ public class CPPPopulateASTViewAction extends CPPASTVisitor implements IPopulate
|
||||||
*/
|
*/
|
||||||
public int visit(
|
public int visit(
|
||||||
IASTParameterDeclaration parameterDeclaration) {
|
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)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processStatement(org.eclipse.cdt.core.dom.ast.IASTStatement)
|
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processStatement(org.eclipse.cdt.core.dom.ast.IASTStatement)
|
||||||
*/
|
*/
|
||||||
public int visit(IASTStatement statement) {
|
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)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processTypeId(org.eclipse.cdt.core.dom.ast.IASTTypeId)
|
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processTypeId(org.eclipse.cdt.core.dom.ast.IASTTypeId)
|
||||||
*/
|
*/
|
||||||
public int visit(IASTTypeId typeId) {
|
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) {
|
private DOMASTNodeLeaf mergeNode(ASTNode node) {
|
||||||
addRoot(node);
|
DOMASTNodeLeaf leaf = addRoot(node);
|
||||||
|
|
||||||
if (node instanceof IASTPreprocessorMacroDefinition)
|
if (node instanceof IASTPreprocessorMacroDefinition)
|
||||||
addRoot(((IASTPreprocessorMacroDefinition)node).getName());
|
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++) {
|
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)
|
if (statements[i] instanceof ASTNode)
|
||||||
mergeNode((ASTNode)statements[i]);
|
leaves[i] = mergeNode((ASTNode)statements[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return leaves;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void mergePreprocessorProblems(IASTProblem[] problems) {
|
public void mergePreprocessorProblems(IASTProblem[] problems) {
|
||||||
|
@ -265,45 +357,26 @@ public class CPPPopulateASTViewAction extends CPPASTVisitor implements IPopulate
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void groupIncludes(IASTPreprocessorStatement[] statements) {
|
public void groupIncludes(DOMASTNodeLeaf[] treeIncludes) {
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// loop through the includes and make sure that all of the nodes
|
// 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)
|
// that are children of the TU are in the proper include (based on offset)
|
||||||
DOMASTNodeLeaf child = null;
|
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;
|
if (treeIncludes[i] == null) continue;
|
||||||
|
|
||||||
for(int j=root.getChildren(false).length-1; j>=0; j--) {
|
IASTNode node = null;
|
||||||
if (monitor != null && monitor.isCanceled()) return;
|
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];
|
child = root.getChildren(false)[j];
|
||||||
|
|
||||||
|
node = treeIncludes[i].getNode();
|
||||||
if (child != null && treeIncludes[i] != child &&
|
if (child != null && treeIncludes[i] != child &&
|
||||||
includes[i] instanceof ASTInclusionStatement &&
|
node instanceof ASTInclusionStatement &&
|
||||||
((ASTNode)child.getNode()).getOffset() >= ((ASTInclusionStatement)includes[i]).startOffset &&
|
((ASTNode)child.getNode()).getOffset() >= ((ASTInclusionStatement)node).startOffset &&
|
||||||
((ASTNode)child.getNode()).getOffset() <= ((ASTInclusionStatement)includes[i]).endOffset) {
|
((ASTNode)child.getNode()).getOffset() <= ((ASTInclusionStatement)node).endOffset)
|
||||||
|
{
|
||||||
root.removeChild(child);
|
root.removeChild(child);
|
||||||
treeIncludes[i].addChild(child);
|
((DOMASTNodeParent)treeIncludes[i]).addChild(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,6 @@ import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
*/
|
*/
|
||||||
public class CPopulateASTViewAction extends CASTVisitor implements IPopulateDOMASTAction {
|
public class CPopulateASTViewAction extends CASTVisitor implements IPopulateDOMASTAction {
|
||||||
private static final int INITIAL_PROBLEM_SIZE = 4;
|
private static final int INITIAL_PROBLEM_SIZE = 4;
|
||||||
private static final int INITIAL_INCLUDE_STATEMENT_SIZE = 8;
|
|
||||||
{
|
{
|
||||||
shouldVisitNames = true;
|
shouldVisitNames = true;
|
||||||
shouldVisitDeclarations = true;
|
shouldVisitDeclarations = true;
|
||||||
|
@ -66,13 +65,27 @@ public class CPopulateASTViewAction extends CASTVisitor implements IPopulateDOMA
|
||||||
this.monitor = monitor;
|
this.monitor = monitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int addRoot(IASTNode node) {
|
private class DOMASTNodeLeafContinue extends DOMASTNodeLeaf {
|
||||||
if (monitor != null && monitor.isCanceled()) return PROCESS_ABORT;
|
public DOMASTNodeLeafContinue(IASTNode node) {
|
||||||
if (node == null) return PROCESS_CONTINUE;
|
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)
|
// only do length check for ASTNode (getNodeLocations on PreprocessorStatements is very expensive)
|
||||||
if (node instanceof ASTNode && ((ASTNode)node).getLength() <= 0)
|
if (node instanceof ASTNode && ((ASTNode)node).getLength() <= 0)
|
||||||
return PROCESS_CONTINUE;
|
return new DOMASTNodeLeafContinue(null);
|
||||||
|
|
||||||
DOMASTNodeParent parent = null;
|
DOMASTNodeParent parent = null;
|
||||||
|
|
||||||
|
@ -91,12 +104,10 @@ public class CPopulateASTViewAction extends CASTVisitor implements IPopulateDOMA
|
||||||
if (parent == null)
|
if (parent == null)
|
||||||
parent = root;
|
parent = root;
|
||||||
|
|
||||||
createNode(parent, node);
|
return createNode(parent, node);
|
||||||
|
|
||||||
return PROCESS_CONTINUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createNode(DOMASTNodeParent parent, IASTNode node) {
|
private DOMASTNodeLeaf createNode(DOMASTNodeParent parent, IASTNode node) {
|
||||||
DOMASTNodeParent tree = new DOMASTNodeParent(node);
|
DOMASTNodeParent tree = new DOMASTNodeParent(node);
|
||||||
parent.addChild(tree);
|
parent.addChild(tree);
|
||||||
|
|
||||||
|
@ -113,20 +124,28 @@ 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 tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (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)
|
||||||
*/
|
*/
|
||||||
public int visit(IASTDeclaration declaration) {
|
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)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processDeclarator(org.eclipse.cdt.core.dom.ast.IASTDeclarator)
|
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processDeclarator(org.eclipse.cdt.core.dom.ast.IASTDeclarator)
|
||||||
*/
|
*/
|
||||||
public int visit(IASTDeclarator declarator) {
|
public int visit(IASTDeclarator declarator) {
|
||||||
int ret = addRoot(declarator);
|
DOMASTNodeLeaf temp = addRoot(declarator);
|
||||||
|
|
||||||
IASTPointerOperator[] ops = declarator.getPointerOperators();
|
IASTPointerOperator[] ops = declarator.getPointerOperators();
|
||||||
for(int i=0; i<ops.length; i++)
|
for(int i=0; i<ops.length; i++)
|
||||||
|
@ -138,50 +157,93 @@ public class CPopulateASTViewAction extends CASTVisitor implements IPopulateDOMA
|
||||||
addRoot(mods[i]);
|
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)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processDesignator(org.eclipse.cdt.core.dom.ast.c.ICASTDesignator)
|
* @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) {
|
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)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processDeclSpecifier(org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier)
|
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processDeclSpecifier(org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier)
|
||||||
*/
|
*/
|
||||||
public int visit(IASTDeclSpecifier declSpec) {
|
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)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processEnumerator(org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator)
|
* @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) {
|
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)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processExpression(org.eclipse.cdt.core.dom.ast.IASTExpression)
|
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processExpression(org.eclipse.cdt.core.dom.ast.IASTExpression)
|
||||||
*/
|
*/
|
||||||
public int visit(IASTExpression expression) {
|
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)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processInitializer(org.eclipse.cdt.core.dom.ast.IASTInitializer)
|
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processInitializer(org.eclipse.cdt.core.dom.ast.IASTInitializer)
|
||||||
*/
|
*/
|
||||||
public int visit(IASTInitializer initializer) {
|
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)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processName(org.eclipse.cdt.core.dom.ast.IASTName)
|
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processName(org.eclipse.cdt.core.dom.ast.IASTName)
|
||||||
*/
|
*/
|
||||||
public int visit(IASTName name) {
|
public int visit(IASTName name) {
|
||||||
|
DOMASTNodeLeaf temp = null;
|
||||||
if ( name.toString() != 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;
|
return PROCESS_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,37 +252,60 @@ public class CPopulateASTViewAction extends CASTVisitor implements IPopulateDOMA
|
||||||
*/
|
*/
|
||||||
public int visit(
|
public int visit(
|
||||||
IASTParameterDeclaration parameterDeclaration) {
|
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)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processStatement(org.eclipse.cdt.core.dom.ast.IASTStatement)
|
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processStatement(org.eclipse.cdt.core.dom.ast.IASTStatement)
|
||||||
*/
|
*/
|
||||||
public int visit(IASTStatement statement) {
|
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)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processTypeId(org.eclipse.cdt.core.dom.ast.IASTTypeId)
|
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processTypeId(org.eclipse.cdt.core.dom.ast.IASTTypeId)
|
||||||
*/
|
*/
|
||||||
public int visit(IASTTypeId typeId) {
|
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) {
|
private DOMASTNodeLeaf mergeNode(ASTNode node) {
|
||||||
addRoot(node);
|
DOMASTNodeLeaf temp = addRoot(node);
|
||||||
|
|
||||||
if (node instanceof IASTPreprocessorMacroDefinition )
|
if (node instanceof IASTPreprocessorMacroDefinition )
|
||||||
addRoot(((IASTPreprocessorMacroDefinition)node).getName());
|
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++) {
|
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)
|
if (statements[i] instanceof ASTNode)
|
||||||
mergeNode((ASTNode)statements[i]);
|
leaves[i] = mergeNode((ASTNode)statements[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return leaves;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void mergePreprocessorProblems(IASTProblem[] problems) {
|
public void mergePreprocessorProblems(IASTProblem[] problems) {
|
||||||
|
@ -236,46 +321,26 @@ public class CPopulateASTViewAction extends CASTVisitor implements IPopulateDOMA
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void groupIncludes(IASTPreprocessorStatement[] statements) {
|
public void groupIncludes(DOMASTNodeLeaf[] treeIncludes) {
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// loop through the includes and make sure that all of the nodes
|
// 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)
|
// that are children of the TU are in the proper include (based on offset)
|
||||||
DOMASTNodeLeaf child = null;
|
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;
|
if (treeIncludes[i] == null) continue;
|
||||||
|
|
||||||
for(int j=root.getChildren(false).length-1; j>=0; j--) {
|
IASTNode node = null;
|
||||||
if (monitor != null && monitor.isCanceled()) return;
|
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];
|
child = root.getChildren(false)[j];
|
||||||
|
|
||||||
|
node = treeIncludes[i].getNode();
|
||||||
if (child != null &&
|
if (child != null &&
|
||||||
treeIncludes[i] != child &&
|
treeIncludes[i] != child &&
|
||||||
includes[i] instanceof ASTInclusionStatement &&
|
node instanceof ASTInclusionStatement &&
|
||||||
((ASTNode)child.getNode()).getOffset() >= ((ASTInclusionStatement)includes[i]).startOffset &&
|
((ASTNode)child.getNode()).getOffset() >= ((ASTInclusionStatement)node).startOffset &&
|
||||||
((ASTNode)child.getNode()).getOffset() <= ((ASTInclusionStatement)includes[i]).endOffset) {
|
((ASTNode)child.getNode()).getOffset() <= ((ASTInclusionStatement)node).endOffset) {
|
||||||
root.removeChild(child);
|
root.removeChild(child);
|
||||||
treeIncludes[i].addChild(child);
|
((DOMASTNodeParent)treeIncludes[i]).addChild(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -404,7 +404,7 @@ public class DOMAST extends ViewPart {
|
||||||
monitor.subTask(MERGING_ + statements.length + _PREPROCESSOR_STATEMENTS_);
|
monitor.subTask(MERGING_ + statements.length + _PREPROCESSOR_STATEMENTS_);
|
||||||
start=System.currentTimeMillis();
|
start=System.currentTimeMillis();
|
||||||
// merge preprocessor statements to the tree
|
// merge preprocessor statements to the tree
|
||||||
action.mergePreprocessorStatements(statements);
|
DOMASTNodeLeaf[] includeStatements = action.mergePreprocessorStatements(statements);
|
||||||
monitor.worked(2);
|
monitor.worked(2);
|
||||||
System.out.println(DOM_AST_VIEW_DONE + MERGING_ + statements.length + _PREPROCESSOR_STATEMENTS_ + COLON_SPACE + (System.currentTimeMillis()- start) );
|
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);
|
monitor.subTask(GROUPING_AST);
|
||||||
start=System.currentTimeMillis();
|
start=System.currentTimeMillis();
|
||||||
// group #includes
|
// group #includes
|
||||||
action.groupIncludes(statements);
|
action.groupIncludes(includeStatements);
|
||||||
monitor.worked(30);
|
monitor.worked(30);
|
||||||
System.out.println(DOM_AST_VIEW_DONE + GROUPING_AST + COLON_SPACE + (System.currentTimeMillis()- start) );
|
System.out.println(DOM_AST_VIEW_DONE + GROUPING_AST + COLON_SPACE + (System.currentTimeMillis()- start) );
|
||||||
|
|
||||||
|
|
|
@ -10,12 +10,10 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.ui.tests.DOMAST;
|
package org.eclipse.cdt.ui.tests.DOMAST;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.lang.reflect.Array;
|
||||||
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.IASTPreprocessorStatement;
|
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;
|
||||||
|
@ -88,22 +86,80 @@ public class DOMASTNodeParent extends DOMASTNodeLeaf {
|
||||||
return children;
|
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() {
|
public void cleanChildren() {
|
||||||
// remove null elements
|
// remove null elements
|
||||||
children = (DOMASTNodeLeaf[])ArrayUtil.removeNulls(DOMASTNodeLeaf.class, children);
|
children = (DOMASTNodeLeaf[])ArrayUtil.removeNulls(DOMASTNodeLeaf.class, children);
|
||||||
|
|
||||||
// sort the elements
|
// sort the elements
|
||||||
Arrays.sort(children, new Comparator() {
|
//if (indexFirstPreproStmnt >= 0) { // TODO Devin what if it's ALL preprocessor statements ?
|
||||||
public int compare(Object a, Object b) {
|
int firstOffset=0;
|
||||||
if(a instanceof DOMASTNodeLeaf && b instanceof DOMASTNodeLeaf &&
|
int firstLength=0;
|
||||||
((DOMASTNodeLeaf)a).getNode() instanceof ASTNode &&
|
int checkOffset=0;
|
||||||
((DOMASTNodeLeaf)b).getNode() instanceof ASTNode) {
|
int checkLength=0;
|
||||||
return ((ASTNode)((DOMASTNodeLeaf)a).getNode()).getOffset() - ((ASTNode)((DOMASTNodeLeaf)b).getNode()).getOffset();
|
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)
|
// 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++) {
|
||||||
|
@ -157,7 +213,7 @@ public class DOMASTNodeParent extends DOMASTNodeLeaf {
|
||||||
if (nodeChain[i] != null) {
|
if (nodeChain[i] != null) {
|
||||||
parentToFind = nodeChain[i];
|
parentToFind = nodeChain[i];
|
||||||
|
|
||||||
for(; j>=indexFirstPreproStmnt; j--) {
|
for(; j>=0; j--) {
|
||||||
if (childrenToSearch[j] instanceof DOMASTNodeParent) {
|
if (childrenToSearch[j] instanceof DOMASTNodeParent) {
|
||||||
if ( childrenToSearch[j].getNode() == node.getParent() ) {
|
if ( childrenToSearch[j].getNode() == node.getParent() ) {
|
||||||
return (DOMASTNodeParent)childrenToSearch[j];
|
return (DOMASTNodeParent)childrenToSearch[j];
|
||||||
|
@ -270,47 +326,6 @@ public class DOMASTNodeParent extends DOMASTNodeLeaf {
|
||||||
if (equalNodes(node, this.getNode(), useOffset)) {
|
if (equalNodes(node, this.getNode(), useOffset)) {
|
||||||
return this;
|
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 )
|
if( children.length == 0 )
|
||||||
return null;
|
return null;
|
||||||
if( !cleanupedElements ){
|
if( !cleanupedElements ){
|
||||||
|
@ -343,9 +358,6 @@ public class DOMASTNodeParent extends DOMASTNodeLeaf {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null; // nothing found
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean equalNodes(IASTNode node1, IASTNode node2, boolean useOffset) {
|
private boolean equalNodes(IASTNode node1, IASTNode node2, boolean useOffset) {
|
||||||
if (useOffset) {
|
if (useOffset) {
|
||||||
if (node1 instanceof ASTNode && node2 instanceof ASTNode) {
|
if (node1 instanceof ASTNode && node2 instanceof ASTNode) {
|
||||||
|
|
|
@ -18,7 +18,7 @@ import org.eclipse.cdt.core.dom.ast.IASTProblem;
|
||||||
*/
|
*/
|
||||||
public interface IPopulateDOMASTAction {
|
public interface IPopulateDOMASTAction {
|
||||||
public DOMASTNodeParent getTree();
|
public DOMASTNodeParent getTree();
|
||||||
public void mergePreprocessorStatements(IASTPreprocessorStatement[] statements);
|
public DOMASTNodeLeaf[] mergePreprocessorStatements(IASTPreprocessorStatement[] statements);
|
||||||
public void mergePreprocessorProblems(IASTProblem[] problems);
|
public void mergePreprocessorProblems(IASTProblem[] problems);
|
||||||
public void groupIncludes(IASTPreprocessorStatement[] statements);
|
public void groupIncludes(DOMASTNodeLeaf[] statements);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue