mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-11 10:15:39 +02:00
Patch for Devin Steffler.
IASTTranslationUnit#getNodeForLocation() Selection in DOM AST View.
This commit is contained in:
parent
7945749d49
commit
511c556400
14 changed files with 959 additions and 195 deletions
|
@ -61,9 +61,7 @@ public interface IASTTranslationUnit extends IASTNode {
|
||||||
|
|
||||||
public IASTNodeLocation[] getLocationInfo(int offset, int length);
|
public IASTNodeLocation[] getLocationInfo(int offset, int length);
|
||||||
|
|
||||||
public IASTNode[] selectNodesForLocation(String path, int offset, int length);
|
public IASTNode selectNodeForLocation(String path, int offset, int length);
|
||||||
|
|
||||||
public IASTNode[] selectNodesForLocation(int offset, int length);
|
|
||||||
|
|
||||||
public IASTPreprocessorMacroDefinition[] getMacroDefinitions();
|
public IASTPreprocessorMacroDefinition[] getMacroDefinitions();
|
||||||
|
|
||||||
|
|
|
@ -11,20 +11,34 @@ package org.eclipse.cdt.internal.core.dom.parser.c;
|
||||||
|
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
|
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.IASTNodeLocation;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
|
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTProblem;
|
import org.eclipse.cdt.core.dom.ast.IASTProblem;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTVisitor;
|
import org.eclipse.cdt.core.dom.ast.IASTVisitor;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.c.ICASTDesignator;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTEnumerator;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.IRequiresLocationInformation;
|
import org.eclipse.cdt.internal.core.dom.parser.IRequiresLocationInformation;
|
||||||
import org.eclipse.cdt.internal.core.parser.scanner2.ILocationResolver;
|
import org.eclipse.cdt.internal.core.parser.scanner2.ILocationResolver;
|
||||||
|
import org.eclipse.cdt.internal.core.parser.scanner2.InvalidPreprocessorNodeException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author jcamelon
|
* @author jcamelon
|
||||||
|
@ -126,13 +140,172 @@ public class CASTTranslationUnit extends CASTNode implements IASTTranslationUnit
|
||||||
return resolver.getLocations(offset,length);
|
return resolver.getLocations(offset,length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class CFindNodeForOffsetAction extends CVisitor.CBaseVisitorAction {
|
||||||
|
{
|
||||||
|
processNames = true;
|
||||||
|
processDeclarations = true;
|
||||||
|
processInitializers = true;
|
||||||
|
processParameterDeclarations = true;
|
||||||
|
processDeclarators = true;
|
||||||
|
processDeclSpecifiers = true;
|
||||||
|
processDesignators = true;
|
||||||
|
processExpressions = true;
|
||||||
|
processStatements = true;
|
||||||
|
processTypeIds = true;
|
||||||
|
processEnumerators = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
IASTNode foundNode = null;
|
||||||
|
int offset = 0;
|
||||||
|
int length = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public CFindNodeForOffsetAction(int offset, int length) {
|
||||||
|
this.offset = offset;
|
||||||
|
this.length = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int processNode(IASTNode node) {
|
||||||
|
if (foundNode != null)
|
||||||
|
return PROCESS_ABORT;
|
||||||
|
|
||||||
|
if (node instanceof ASTNode &&
|
||||||
|
((ASTNode)node).getOffset() == offset &&
|
||||||
|
((ASTNode)node).getLength() == length) {
|
||||||
|
foundNode = node;
|
||||||
|
return PROCESS_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// skip the rest of this node if the selection is outside of its bounds
|
||||||
|
if (node instanceof ASTNode &&
|
||||||
|
offset > ((ASTNode)node).getOffset() + ((ASTNode)node).getLength())
|
||||||
|
return PROCESS_SKIP;
|
||||||
|
|
||||||
|
return PROCESS_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processDeclaration(org.eclipse.cdt.core.dom.ast.IASTDeclaration)
|
||||||
|
*/
|
||||||
|
public int processDeclaration(IASTDeclaration declaration) {
|
||||||
|
// use declarations to determine if the search has gone past the offset (i.e. don't know the order the visitor visits the nodes)
|
||||||
|
if (declaration instanceof ASTNode && ((ASTNode)declaration).getOffset() > offset)
|
||||||
|
return PROCESS_ABORT;
|
||||||
|
|
||||||
|
return processNode(declaration);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processDeclarator(org.eclipse.cdt.core.dom.ast.IASTDeclarator)
|
||||||
|
*/
|
||||||
|
public int processDeclarator(IASTDeclarator declarator) {
|
||||||
|
int ret = processNode(declarator);
|
||||||
|
|
||||||
|
IASTPointerOperator[] ops = declarator.getPointerOperators();
|
||||||
|
for(int i=0; i<ops.length; i++)
|
||||||
|
processNode(ops[i]);
|
||||||
|
|
||||||
|
if (declarator instanceof IASTArrayDeclarator) {
|
||||||
|
IASTArrayModifier[] mods = ((IASTArrayDeclarator)declarator).getArrayModifiers();
|
||||||
|
for(int i=0; i<mods.length; i++)
|
||||||
|
processNode(mods[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processDesignator(org.eclipse.cdt.core.dom.ast.c.ICASTDesignator)
|
||||||
|
*/
|
||||||
|
public int processDesignator(ICASTDesignator designator) {
|
||||||
|
return processNode(designator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processDeclSpecifier(org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier)
|
||||||
|
*/
|
||||||
|
public int processDeclSpecifier(IASTDeclSpecifier declSpec) {
|
||||||
|
return processNode(declSpec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processEnumerator(org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator)
|
||||||
|
*/
|
||||||
|
public int processEnumerator(IASTEnumerator enumerator) {
|
||||||
|
return processNode((IASTNode)enumerator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processExpression(org.eclipse.cdt.core.dom.ast.IASTExpression)
|
||||||
|
*/
|
||||||
|
public int processExpression(IASTExpression expression) {
|
||||||
|
return processNode(expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processInitializer(org.eclipse.cdt.core.dom.ast.IASTInitializer)
|
||||||
|
*/
|
||||||
|
public int processInitializer(IASTInitializer initializer) {
|
||||||
|
return processNode(initializer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processName(org.eclipse.cdt.core.dom.ast.IASTName)
|
||||||
|
*/
|
||||||
|
public int processName(IASTName name) {
|
||||||
|
if ( name.toString() != null )
|
||||||
|
return processNode(name);
|
||||||
|
return PROCESS_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processParameterDeclaration(org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration)
|
||||||
|
*/
|
||||||
|
public int processParameterDeclaration(
|
||||||
|
IASTParameterDeclaration parameterDeclaration) {
|
||||||
|
return processNode(parameterDeclaration);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processStatement(org.eclipse.cdt.core.dom.ast.IASTStatement)
|
||||||
|
*/
|
||||||
|
public int processStatement(IASTStatement statement) {
|
||||||
|
return processNode(statement);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processTypeId(org.eclipse.cdt.core.dom.ast.IASTTypeId)
|
||||||
|
*/
|
||||||
|
public int processTypeId(IASTTypeId typeId) {
|
||||||
|
return processNode(typeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IASTNode getNode() {
|
||||||
|
return foundNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.core.dom.ast.IASTTranslationUnit#getNodeForLocation(org.eclipse.cdt.core.dom.ast.IASTNodeLocation)
|
* @see org.eclipse.cdt.core.dom.ast.IASTTranslationUnit#getNodeForLocation(org.eclipse.cdt.core.dom.ast.IASTNodeLocation)
|
||||||
*/
|
*/
|
||||||
public IASTNode[] selectNodesForLocation(String path, int offset, int length) {
|
public IASTNode selectNodeForLocation(String path, int realOffset, int realLength) {
|
||||||
// TODO Auto-generated method stub
|
IASTNode node = null;
|
||||||
return null;
|
|
||||||
|
try {
|
||||||
|
node = resolver.getPreprocessorNode(path, realOffset, realLength);
|
||||||
|
} catch (InvalidPreprocessorNodeException ipne) {
|
||||||
|
// extract global offset from the exception, use it to get the node from the AST if it's valid
|
||||||
|
int globalOffset = ipne.getGlobalOffset();
|
||||||
|
if (globalOffset >= 0) {
|
||||||
|
CFindNodeForOffsetAction nodeFinder = new CFindNodeForOffsetAction(globalOffset, realLength);
|
||||||
|
getVisitor().visitTranslationUnit(nodeFinder);
|
||||||
|
node = nodeFinder.getNode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -190,13 +363,6 @@ public class CASTTranslationUnit extends CASTNode implements IASTTranslationUnit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.cdt.core.dom.ast.IASTTranslationUnit#selectNodesForLocation(int, int)
|
|
||||||
*/
|
|
||||||
public IASTNode[] selectNodesForLocation(int offset, int length) {
|
|
||||||
return selectNodesForLocation( "", offset, length ); //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see java.lang.Object#finalize()
|
* @see java.lang.Object#finalize()
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -11,24 +11,42 @@
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
|
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.IASTNodeLocation;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
|
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTProblem;
|
import org.eclipse.cdt.core.dom.ast.IASTProblem;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTVisitor;
|
import org.eclipse.cdt.core.dom.ast.IASTVisitor;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.c.ICASTDesignator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionTryBlockDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisitor;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisitor;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTEnumerator;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.IRequiresLocationInformation;
|
import org.eclipse.cdt.internal.core.dom.parser.IRequiresLocationInformation;
|
||||||
import org.eclipse.cdt.internal.core.parser.scanner2.ILocationResolver;
|
import org.eclipse.cdt.internal.core.parser.scanner2.ILocationResolver;
|
||||||
|
import org.eclipse.cdt.internal.core.parser.scanner2.InvalidPreprocessorNodeException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author jcamelon
|
* @author jcamelon
|
||||||
|
@ -146,13 +164,189 @@ public class CPPASTTranslationUnit extends CPPASTNode implements
|
||||||
return resolver.getLocations(offset, length);
|
return resolver.getLocations(offset, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class CPPFindNodeForOffsetAction extends CPPVisitor.CPPBaseVisitorAction {
|
||||||
|
{
|
||||||
|
processNames = true;
|
||||||
|
processDeclarations = true;
|
||||||
|
processInitializers = true;
|
||||||
|
processParameterDeclarations = true;
|
||||||
|
processDeclarators = true;
|
||||||
|
processDeclSpecifiers = true;
|
||||||
|
processExpressions = true;
|
||||||
|
processStatements = true;
|
||||||
|
processTypeIds = true;
|
||||||
|
processEnumerators = true;
|
||||||
|
processBaseSpecifiers = true;
|
||||||
|
processNamespaces = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
IASTNode foundNode = null;
|
||||||
|
int offset = 0;
|
||||||
|
int length = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public CPPFindNodeForOffsetAction(int offset, int length) {
|
||||||
|
this.offset = offset;
|
||||||
|
this.length = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int processNode(IASTNode node) {
|
||||||
|
if (foundNode != null)
|
||||||
|
return PROCESS_ABORT;
|
||||||
|
|
||||||
|
if (node instanceof ASTNode &&
|
||||||
|
((ASTNode)node).getOffset() == offset &&
|
||||||
|
((ASTNode)node).getLength() == length) {
|
||||||
|
foundNode = node;
|
||||||
|
return PROCESS_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// skip the rest of this node if the selection is outside of its bounds
|
||||||
|
if (node instanceof ASTNode &&
|
||||||
|
offset > ((ASTNode)node).getOffset() + ((ASTNode)node).getLength())
|
||||||
|
return PROCESS_SKIP;
|
||||||
|
|
||||||
|
return PROCESS_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processDeclaration(org.eclipse.cdt.core.dom.ast.IASTDeclaration)
|
||||||
|
*/
|
||||||
|
public int processDeclaration(IASTDeclaration declaration) {
|
||||||
|
// use declarations to determine if the search has gone past the offset (i.e. don't know the order the visitor visits the nodes)
|
||||||
|
if (declaration instanceof ASTNode && ((ASTNode)declaration).getOffset() > offset)
|
||||||
|
return PROCESS_ABORT;
|
||||||
|
|
||||||
|
return processNode(declaration);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction#processDeclarator(org.eclipse.cdt.core.dom.ast.IASTDeclarator)
|
||||||
|
*/
|
||||||
|
public int processDeclarator(IASTDeclarator declarator) {
|
||||||
|
int ret = processNode(declarator);
|
||||||
|
|
||||||
|
IASTPointerOperator[] ops = declarator.getPointerOperators();
|
||||||
|
for(int i=0; i<ops.length; i++)
|
||||||
|
processNode(ops[i]);
|
||||||
|
|
||||||
|
if (declarator instanceof IASTArrayDeclarator) {
|
||||||
|
IASTArrayModifier[] mods = ((IASTArrayDeclarator)declarator).getArrayModifiers();
|
||||||
|
for(int i=0; i<mods.length; i++)
|
||||||
|
processNode(mods[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (declarator instanceof ICPPASTFunctionDeclarator) {
|
||||||
|
ICPPASTConstructorChainInitializer[] chainInit = ((ICPPASTFunctionDeclarator)declarator).getConstructorChain();
|
||||||
|
for(int i=0; i<chainInit.length; i++) {
|
||||||
|
processNode(chainInit[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( declarator instanceof ICPPASTFunctionTryBlockDeclarator ){
|
||||||
|
ICPPASTCatchHandler [] catchHandlers = ((ICPPASTFunctionTryBlockDeclarator)declarator).getCatchHandlers();
|
||||||
|
for( int i = 0; i < catchHandlers.length; i++ ){
|
||||||
|
processNode(catchHandlers[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processDesignator(org.eclipse.cdt.core.dom.ast.c.ICASTDesignator)
|
||||||
|
*/
|
||||||
|
public int processDesignator(ICASTDesignator designator) {
|
||||||
|
return processNode(designator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processDeclSpecifier(org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier)
|
||||||
|
*/
|
||||||
|
public int processDeclSpecifier(IASTDeclSpecifier declSpec) {
|
||||||
|
return processNode(declSpec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processEnumerator(org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator)
|
||||||
|
*/
|
||||||
|
public int processEnumerator(IASTEnumerator enumerator) {
|
||||||
|
return processNode((IASTNode)enumerator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processExpression(org.eclipse.cdt.core.dom.ast.IASTExpression)
|
||||||
|
*/
|
||||||
|
public int processExpression(IASTExpression expression) {
|
||||||
|
return processNode(expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processInitializer(org.eclipse.cdt.core.dom.ast.IASTInitializer)
|
||||||
|
*/
|
||||||
|
public int processInitializer(IASTInitializer initializer) {
|
||||||
|
return processNode(initializer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processName(org.eclipse.cdt.core.dom.ast.IASTName)
|
||||||
|
*/
|
||||||
|
public int processName(IASTName name) {
|
||||||
|
if ( name.toString() != null )
|
||||||
|
return processNode(name);
|
||||||
|
return PROCESS_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processParameterDeclaration(org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration)
|
||||||
|
*/
|
||||||
|
public int processParameterDeclaration(
|
||||||
|
IASTParameterDeclaration parameterDeclaration) {
|
||||||
|
return processNode(parameterDeclaration);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processStatement(org.eclipse.cdt.core.dom.ast.IASTStatement)
|
||||||
|
*/
|
||||||
|
public int processStatement(IASTStatement statement) {
|
||||||
|
return processNode(statement);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processTypeId(org.eclipse.cdt.core.dom.ast.IASTTypeId)
|
||||||
|
*/
|
||||||
|
public int processTypeId(IASTTypeId typeId) {
|
||||||
|
return processNode(typeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IASTNode getNode() {
|
||||||
|
return foundNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
*
|
||||||
* @see org.eclipse.cdt.core.dom.ast.IASTTranslationUnit#getNodeForLocation(org.eclipse.cdt.core.dom.ast.IASTNodeLocation)
|
* @see org.eclipse.cdt.core.dom.ast.IASTTranslationUnit#getNodeForLocation(org.eclipse.cdt.core.dom.ast.IASTNodeLocation)
|
||||||
*/
|
*/
|
||||||
public IASTNode[] selectNodesForLocation(String path, int offset, int length) {
|
public IASTNode selectNodeForLocation(String path, int realOffset, int realLength) {
|
||||||
return null;
|
IASTNode node = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
node = resolver.getPreprocessorNode(path, realOffset, realLength);
|
||||||
|
} catch (InvalidPreprocessorNodeException ipne) {
|
||||||
|
// extract global offset from the exception, use it to get the node from the AST if it's valid
|
||||||
|
int globalOffset = ipne.getGlobalOffset();
|
||||||
|
if (globalOffset >= 0) {
|
||||||
|
CPPFindNodeForOffsetAction nodeFinder = new CPPFindNodeForOffsetAction(globalOffset, realLength);
|
||||||
|
getVisitor().visitTranslationUnit(nodeFinder);
|
||||||
|
node = nodeFinder.getNode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -213,19 +407,6 @@ public class CPPASTTranslationUnit extends CPPASTNode implements
|
||||||
this.resolver = resolver;
|
this.resolver = resolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see org.eclipse.cdt.core.dom.ast.IASTTranslationUnit#selectNodesForLocation(int,
|
|
||||||
* int)
|
|
||||||
*/
|
|
||||||
public IASTNode[] selectNodesForLocation(int offset, int length) {
|
|
||||||
if (resolver == null)
|
|
||||||
return EMPTY_NODE_ARRAY;
|
|
||||||
return selectNodesForLocation(resolver.getTranslationUnitPath(),
|
|
||||||
offset, length); //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.parser.scanner2;
|
package org.eclipse.cdt.internal.core.parser.scanner2;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
|
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
|
||||||
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;
|
||||||
|
@ -26,7 +27,6 @@ public interface ILocationResolver {
|
||||||
public IASTPreprocessorStatement [] getAllPreprocessorStatements();
|
public IASTPreprocessorStatement [] getAllPreprocessorStatements();
|
||||||
|
|
||||||
public IASTNodeLocation [] getLocations( int offset, int length );
|
public IASTNodeLocation [] getLocations( int offset, int length );
|
||||||
public IASTNodeLocation getLocation( int offset );
|
|
||||||
|
|
||||||
public char [] getUnpreprocessedSignature( IASTNodeLocation [] locations );
|
public char [] getUnpreprocessedSignature( IASTNodeLocation [] locations );
|
||||||
|
|
||||||
|
@ -36,4 +36,6 @@ public interface ILocationResolver {
|
||||||
|
|
||||||
public void cleanup();
|
public void cleanup();
|
||||||
|
|
||||||
|
public IASTNode getPreprocessorNode( String path, int offset, int length ) throws InvalidPreprocessorNodeException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
/**********************************************************************
|
||||||
|
* Copyright (c) 2005 IBM Corporation and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Common Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/cpl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM - Initial API and implementation
|
||||||
|
**********************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.parser.scanner2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dsteffle
|
||||||
|
*/
|
||||||
|
public class InvalidPreprocessorNodeException extends Exception {
|
||||||
|
|
||||||
|
public InvalidPreprocessorNodeException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public InvalidPreprocessorNodeException(String message, int offset) {
|
||||||
|
super(message);
|
||||||
|
globalOffset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int globalOffset = -1;
|
||||||
|
|
||||||
|
public int getGlobalOffset() {
|
||||||
|
return globalOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGlobalOffset(int offset) {
|
||||||
|
globalOffset = offset;
|
||||||
|
}
|
||||||
|
}
|
|
@ -46,7 +46,9 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
*/
|
*/
|
||||||
public class LocationMap implements ILocationResolver, IScannerPreprocessorLog {
|
public class LocationMap implements ILocationResolver, IScannerPreprocessorLog {
|
||||||
|
|
||||||
/**
|
private static final String NOT_VALID_MACRO = "Not a valid macro selection"; //$NON-NLS-1$
|
||||||
|
private static final String TU_INCLUDE_NOT_FOUND = "File searching does not match TU or #includes."; //$NON-NLS-1$
|
||||||
|
/**
|
||||||
* @author jcamelon
|
* @author jcamelon
|
||||||
*/
|
*/
|
||||||
static class ASTEndif extends ScannerASTNode implements
|
static class ASTEndif extends ScannerASTNode implements
|
||||||
|
@ -1024,33 +1026,40 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog {
|
||||||
collectContexts(V_PREPROCESSOR, tu, contexts, 0);
|
collectContexts(V_PREPROCESSOR, tu, contexts, 0);
|
||||||
IASTPreprocessorStatement[] result = new IASTPreprocessorStatement[size];
|
IASTPreprocessorStatement[] result = new IASTPreprocessorStatement[size];
|
||||||
for (int i = 0; i < size; ++i) {
|
for (int i = 0; i < size; ++i) {
|
||||||
if (contexts[i] instanceof _Inclusion)
|
result[i] = createPreprocessorStatement(contexts[i]);
|
||||||
result[i] = createASTInclusion(((_Inclusion) contexts[i]));
|
|
||||||
else if (contexts[i] instanceof _MacroDefinition)
|
|
||||||
result[i] = createASTMacroDefinition((_MacroDefinition) contexts[i]);
|
|
||||||
else if (contexts[i] instanceof _Undef)
|
|
||||||
result[i] = createASTUndef((_Undef) contexts[i]);
|
|
||||||
else if (contexts[i] instanceof _Pragma)
|
|
||||||
result[i] = createASTPragma((_Pragma) contexts[i]);
|
|
||||||
else if (contexts[i] instanceof _Error)
|
|
||||||
result[i] = createASTError((_Error) contexts[i]);
|
|
||||||
else if (contexts[i] instanceof _If)
|
|
||||||
result[i] = createASTIf((_If) contexts[i]);
|
|
||||||
else if (contexts[i] instanceof _Ifdef)
|
|
||||||
result[i] = createASTIfdef((_Ifdef) contexts[i]);
|
|
||||||
else if (contexts[i] instanceof _Ifndef)
|
|
||||||
result[i] = createASTIfndef((_Ifndef) contexts[i]);
|
|
||||||
else if (contexts[i] instanceof _Else)
|
|
||||||
result[i] = createASTElse((_Else) contexts[i]);
|
|
||||||
else if (contexts[i] instanceof _Elif)
|
|
||||||
result[i] = createASTElif((_Elif) contexts[i]);
|
|
||||||
else if (contexts[i] instanceof _Endif)
|
|
||||||
result[i] = createASTEndif((_Endif) contexts[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IASTPreprocessorStatement createPreprocessorStatement(_Context context) {
|
||||||
|
IASTPreprocessorStatement result = null;
|
||||||
|
if (context instanceof _Inclusion)
|
||||||
|
result = createASTInclusion(((_Inclusion) context));
|
||||||
|
else if (context instanceof _MacroDefinition)
|
||||||
|
result = createASTMacroDefinition((_MacroDefinition) context);
|
||||||
|
else if (context instanceof _Undef)
|
||||||
|
result = createASTUndef((_Undef) context);
|
||||||
|
else if (context instanceof _Pragma)
|
||||||
|
result = createASTPragma((_Pragma) context);
|
||||||
|
else if (context instanceof _Error)
|
||||||
|
result = createASTError((_Error) context);
|
||||||
|
else if (context instanceof _If)
|
||||||
|
result = createASTIf((_If) context);
|
||||||
|
else if (context instanceof _Ifdef)
|
||||||
|
result = createASTIfdef((_Ifdef) context);
|
||||||
|
else if (context instanceof _Ifndef)
|
||||||
|
result = createASTIfndef((_Ifndef) context);
|
||||||
|
else if (context instanceof _Else)
|
||||||
|
result = createASTElse((_Else) context);
|
||||||
|
else if (context instanceof _Elif)
|
||||||
|
result = createASTElif((_Elif) context);
|
||||||
|
else if (context instanceof _Endif)
|
||||||
|
result = createASTEndif((_Endif) context);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param endif
|
* @param endif
|
||||||
* @return
|
* @return
|
||||||
|
@ -1280,16 +1289,6 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog {
|
||||||
return bestContext;
|
return bestContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see org.eclipse.cdt.internal.core.parser.scanner2.ILocationResolver#getLocation(int)
|
|
||||||
*/
|
|
||||||
public IASTNodeLocation getLocation(int offset) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
*
|
||||||
|
@ -1694,4 +1693,93 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog {
|
||||||
endOffset, taken));
|
endOffset, taken));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _Context findInclusion(_CompositeContext context, String path) {
|
||||||
|
_Context foundContext = null;
|
||||||
|
List contexts = context.getSubContexts();
|
||||||
|
|
||||||
|
for (int i=0; foundContext == null && i<contexts.size(); i++) {
|
||||||
|
if (contexts.get(i) instanceof _Inclusion) {
|
||||||
|
context = (_Inclusion)contexts.get(i);
|
||||||
|
|
||||||
|
// check if the file matches the #include
|
||||||
|
if (CharArrayUtils.equals(((_Inclusion)context).reader.filename, path.toCharArray())) {
|
||||||
|
foundContext = context;
|
||||||
|
} else {
|
||||||
|
foundContext = findInclusion(context, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return foundContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IASTNode getPreprocessorNode(int globalOffset, int length, _Context startContext) throws InvalidPreprocessorNodeException {
|
||||||
|
IASTNode result = null;
|
||||||
|
if (!(startContext instanceof _CompositeContext)) throw new InvalidPreprocessorNodeException(NOT_VALID_MACRO, globalOffset);
|
||||||
|
List contexts = ((_CompositeContext)startContext).getSubContexts();
|
||||||
|
|
||||||
|
// check if a macro in the location map is the selection
|
||||||
|
for (int i=0; result == null && i<contexts.size(); i++) {
|
||||||
|
if (contexts.get(i) instanceof _Context) {
|
||||||
|
_Context context = (_Context)contexts.get(i);
|
||||||
|
|
||||||
|
// if offset is past the _Context then increment globalOffset
|
||||||
|
if (globalOffset > context.context_directive_end) {
|
||||||
|
globalOffset += context.context_ends - context.context_directive_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if the _Context is the selection
|
||||||
|
if (globalOffset == context.context_directive_start &&
|
||||||
|
length == context.context_directive_end - context.context_directive_start) {
|
||||||
|
result = createPreprocessorStatement(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if a sub node of the macro is the selection // TODO determine how this can be kept in sync with logic in getAllPreprocessorStatements (i.e. 1:1 mapping)
|
||||||
|
if (context instanceof _MacroDefinition) {
|
||||||
|
if (globalOffset == ((_MacroDefinition)context).nameOffset
|
||||||
|
&& length == ((_MacroDefinition)context).name.length)
|
||||||
|
result = createASTMacroDefinition((_MacroDefinition)context).getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
// stop searching the _Contexts if they've gone past the selection
|
||||||
|
if (globalOffset < context.context_directive_end)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == null)
|
||||||
|
throw new InvalidPreprocessorNodeException(NOT_VALID_MACRO, globalOffset);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.internal.core.parser.scanner2.ILocationResolver#getPreprocessorNode(int, int)
|
||||||
|
*/
|
||||||
|
public IASTNode getPreprocessorNode(String path, int offset, int length) throws InvalidPreprocessorNodeException {
|
||||||
|
IASTNode result = null;
|
||||||
|
int globalOffset = 0;
|
||||||
|
_Context foundContext = tu;
|
||||||
|
|
||||||
|
// is the selection in TU or an #include else it's an exception
|
||||||
|
if (CharArrayUtils.equals(tu.reader.filename, path.toCharArray())) {
|
||||||
|
globalOffset = offset; // in TU so start at the real offset
|
||||||
|
} else {
|
||||||
|
foundContext = findInclusion(tu, path);
|
||||||
|
|
||||||
|
if (foundContext == null) {
|
||||||
|
throw new InvalidPreprocessorNodeException(TU_INCLUDE_NOT_FOUND, globalOffset);
|
||||||
|
} else if (foundContext instanceof _Inclusion){
|
||||||
|
globalOffset = foundContext.context_directive_end + offset; // start at #include's directive_end + real offset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = getPreprocessorNode(globalOffset, length, foundContext);
|
||||||
|
|
||||||
|
if (result == null)
|
||||||
|
throw new InvalidPreprocessorNodeException(NOT_VALID_MACRO, globalOffset);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -92,6 +92,15 @@
|
||||||
</or>
|
</or>
|
||||||
</visibility>
|
</visibility>
|
||||||
</viewerContribution>
|
</viewerContribution>
|
||||||
|
<viewerContribution
|
||||||
|
targetID="#CEditorContext"
|
||||||
|
id="org.eclipse.cdt.ui.tests.cEditorContribution">
|
||||||
|
<action
|
||||||
|
label="Show IASTNode in DOM View"
|
||||||
|
class="org.eclipse.cdt.ui.tests.DOMAST.ShowInDOMViewAction"
|
||||||
|
menubarPath="additions"
|
||||||
|
id="org.eclipse.cdt.ui.tests.DOMAST.ShowInDOMViewAction1"/>
|
||||||
|
</viewerContribution>
|
||||||
</extension>
|
</extension>
|
||||||
<extension
|
<extension
|
||||||
point="org.eclipse.cdt.ui.CElementFilters">
|
point="org.eclipse.cdt.ui.CElementFilters">
|
||||||
|
|
|
@ -263,7 +263,7 @@ public class CPPPopulateASTViewAction extends CPPBaseVisitorAction implements IP
|
||||||
TreeParent[] treeIncludes = new TreeParent[includes.length];
|
TreeParent[] treeIncludes = new TreeParent[includes.length];
|
||||||
for (int i=0; i<treeIncludes.length; i++) {
|
for (int i=0; i<treeIncludes.length; i++) {
|
||||||
if (monitor != null && monitor.isCanceled()) return;
|
if (monitor != null && monitor.isCanceled()) return;
|
||||||
treeIncludes[i] = root.findTreeObject(includes[i]);
|
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
|
||||||
|
|
|
@ -236,7 +236,7 @@ public class CPopulateASTViewAction extends CBaseVisitorAction implements IPopul
|
||||||
TreeParent[] treeIncludes = new TreeParent[includes.length];
|
TreeParent[] treeIncludes = new TreeParent[includes.length];
|
||||||
for (int i=0; i<treeIncludes.length; i++) {
|
for (int i=0; i<treeIncludes.length; i++) {
|
||||||
if (monitor != null && monitor.isCanceled()) return;
|
if (monitor != null && monitor.isCanceled()) return;
|
||||||
treeIncludes[i] = root.findTreeObject(includes[i]);
|
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
|
||||||
|
|
|
@ -67,6 +67,7 @@ import org.eclipse.jface.action.IToolBarManager;
|
||||||
import org.eclipse.jface.action.MenuManager;
|
import org.eclipse.jface.action.MenuManager;
|
||||||
import org.eclipse.jface.action.Separator;
|
import org.eclipse.jface.action.Separator;
|
||||||
import org.eclipse.jface.dialogs.MessageDialog;
|
import org.eclipse.jface.dialogs.MessageDialog;
|
||||||
|
import org.eclipse.jface.viewers.IContentProvider;
|
||||||
import org.eclipse.jface.viewers.ISelection;
|
import org.eclipse.jface.viewers.ISelection;
|
||||||
import org.eclipse.jface.viewers.ISelectionChangedListener;
|
import org.eclipse.jface.viewers.ISelectionChangedListener;
|
||||||
import org.eclipse.jface.viewers.IStructuredContentProvider;
|
import org.eclipse.jface.viewers.IStructuredContentProvider;
|
||||||
|
@ -83,6 +84,7 @@ import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.graphics.Image;
|
import org.eclipse.swt.graphics.Image;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.swt.widgets.Menu;
|
import org.eclipse.swt.widgets.Menu;
|
||||||
|
import org.eclipse.swt.widgets.Shell;
|
||||||
import org.eclipse.swt.widgets.Tree;
|
import org.eclipse.swt.widgets.Tree;
|
||||||
import org.eclipse.swt.widgets.TreeItem;
|
import org.eclipse.swt.widgets.TreeItem;
|
||||||
import org.eclipse.ui.IActionBars;
|
import org.eclipse.ui.IActionBars;
|
||||||
|
@ -90,41 +92,32 @@ import org.eclipse.ui.IEditorPart;
|
||||||
import org.eclipse.ui.ISharedImages;
|
import org.eclipse.ui.ISharedImages;
|
||||||
import org.eclipse.ui.IViewPart;
|
import org.eclipse.ui.IViewPart;
|
||||||
import org.eclipse.ui.IWorkbenchActionConstants;
|
import org.eclipse.ui.IWorkbenchActionConstants;
|
||||||
|
import org.eclipse.ui.IWorkbenchPartSite;
|
||||||
import org.eclipse.ui.PartInitException;
|
import org.eclipse.ui.PartInitException;
|
||||||
import org.eclipse.ui.PlatformUI;
|
import org.eclipse.ui.PlatformUI;
|
||||||
import org.eclipse.ui.part.DrillDownAdapter;
|
import org.eclipse.ui.part.DrillDownAdapter;
|
||||||
import org.eclipse.ui.part.ViewPart;
|
import org.eclipse.ui.part.ViewPart;
|
||||||
|
import org.eclipse.ui.progress.WorkbenchJob;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This sample class demonstrates how to plug-in a new workbench view. The view
|
* This is a simple DOM AST View used for development testing.
|
||||||
* shows data obtained from the model. The sample creates a dummy model on the
|
|
||||||
* fly, but a real implementation would connect to the model available either in
|
|
||||||
* this or another plug-in (e.g. the workspace). The view is connected to the
|
|
||||||
* model using a content provider.
|
|
||||||
* <p>
|
|
||||||
* The view uses a label provider to define how model objects should be
|
|
||||||
* presented in the view. Each view can present the same model objects using
|
|
||||||
* different labels and icons, if needed. Alternatively, a single label provider
|
|
||||||
* can be shared between views in order to ensure that objects of the same type
|
|
||||||
* are presented in the same way everywhere.
|
|
||||||
* <p>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class DOMAST extends ViewPart {
|
public class DOMAST extends ViewPart {
|
||||||
private static final String DOM_AST_HAS_NO_CONTENT = "DOM AST has no content"; //$NON-NLS-1$
|
private static final String NOT_VALID_COMPILATION_UNIT = "The active editor does not contain a valid compilation unit."; //$NON-NLS-1$
|
||||||
private static final String SEARCH_FOR_IASTNAME = "Search for IASTName"; //$NON-NLS-1$
|
|
||||||
private static final String CLEAR = "Clear"; //$NON-NLS-1$
|
|
||||||
private static final String DOMAST_FILTER_GROUP_ID = "org.eclipse.cdt.ui.tests.DOMAST.DOMASTFilterGroup"; //$NON-NLS-1$
|
|
||||||
private static final String EXTENSION_CXX = "CXX"; //$NON-NLS-1$
|
private static final String EXTENSION_CXX = "CXX"; //$NON-NLS-1$
|
||||||
private static final String EXTENSION_CPP = "CPP"; //$NON-NLS-1$
|
private static final String EXTENSION_CPP = "CPP"; //$NON-NLS-1$
|
||||||
private static final String EXTENSION_CC = "CC"; //$NON-NLS-1$
|
private static final String EXTENSION_CC = "CC"; //$NON-NLS-1$
|
||||||
private static final String EXTENSION_C = "C"; //$NON-NLS-1$
|
private static final String EXTENSION_C = "C"; //$NON-NLS-1$
|
||||||
private static final String NOT_VALID_COMPILATION_UNIT = "The active editor does not contain a valid compilation unit."; //$NON-NLS-1$
|
private static final String DOM_AST_HAS_NO_CONTENT = "DOM AST has no content"; //$NON-NLS-1$
|
||||||
|
private static final String SEARCH_FOR_IASTNAME = "Search for IASTName"; //$NON-NLS-1$
|
||||||
|
private static final String CLEAR = "Clear"; //$NON-NLS-1$
|
||||||
|
private static final String DOMAST_FILTER_GROUP_ID = "org.eclipse.cdt.ui.tests.DOMAST.DOMASTFilterGroup"; //$NON-NLS-1$
|
||||||
private static final String LOAD_ACTIVE_EDITOR = "Load Active Editor"; //$NON-NLS-1$
|
private static final String LOAD_ACTIVE_EDITOR = "Load Active Editor"; //$NON-NLS-1$
|
||||||
private static final String COLLAPSE_ALL = "Collapse ALL"; //$NON-NLS-1$
|
private static final String COLLAPSE_ALL = "Collapse ALL"; //$NON-NLS-1$
|
||||||
private static final String EXPAND_ALL = "Expand All"; //$NON-NLS-1$
|
private static final String EXPAND_ALL = "Expand All"; //$NON-NLS-1$
|
||||||
private static final String REFRESH_DOM_AST = "Refresh DOM AST"; //$NON-NLS-1$
|
private static final String REFRESH_DOM_AST = "Refresh DOM AST"; //$NON-NLS-1$
|
||||||
private static final String VIEW_NAME = "DOM View"; //$NON-NLS-1$
|
public static final String VIEW_NAME = "DOM View"; //$NON-NLS-1$
|
||||||
private static final String POPUPMENU = "#PopupMenu"; //$NON-NLS-1$
|
private static final String POPUPMENU = "#PopupMenu"; //$NON-NLS-1$
|
||||||
private static final String OPEN_DECLARATIONS = "Open Declarations"; //$NON-NLS-1$
|
private static final String OPEN_DECLARATIONS = "Open Declarations"; //$NON-NLS-1$
|
||||||
private static final String OPEN_REFERENCES = "Open References"; //$NON-NLS-1$
|
private static final String OPEN_REFERENCES = "Open References"; //$NON-NLS-1$
|
||||||
|
@ -145,6 +138,8 @@ public class DOMAST extends ViewPart {
|
||||||
|
|
||||||
private CustomFiltersActionGroup customFiltersActionGroup;
|
private CustomFiltersActionGroup customFiltersActionGroup;
|
||||||
|
|
||||||
|
private static ViewContentProvider.StartInitializingASTView initializeASTViewJob = null;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The content provider class is responsible for providing objects to the
|
* The content provider class is responsible for providing objects to the
|
||||||
* view. It can wrap existing objects in adapters or simply return objects
|
* view. It can wrap existing objects in adapters or simply return objects
|
||||||
|
@ -167,8 +162,8 @@ public class DOMAST extends ViewPart {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ViewContentProvider(IFile file, Object[] expanded) {
|
public ViewContentProvider(IFile file, Object[] expanded) {
|
||||||
StartInitializingASTView job = new StartInitializingASTView(new InitializeView(POPULATING_AST_VIEW, this, viewer, file), expanded);
|
initializeASTViewJob = new StartInitializingASTView(new InitializeView(POPULATING_AST_VIEW, this, viewer, file), expanded);
|
||||||
job.schedule();
|
initializeASTViewJob.schedule();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,6 +172,7 @@ public class DOMAST extends ViewPart {
|
||||||
for(int i=0; i<invisibleRoot.getChildren().length; i++) {
|
for(int i=0; i<invisibleRoot.getChildren().length; i++) {
|
||||||
if (invisibleRoot.getChildren()[i] instanceof TreeParent && invisibleRoot.getChildren()[i].getNode() instanceof IASTTranslationUnit){
|
if (invisibleRoot.getChildren()[i] instanceof TreeParent && invisibleRoot.getChildren()[i].getNode() instanceof IASTTranslationUnit){
|
||||||
tuTreeParent = (TreeParent)invisibleRoot.getChildren()[i];
|
tuTreeParent = (TreeParent)invisibleRoot.getChildren()[i];
|
||||||
|
return tuTreeParent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -452,6 +448,72 @@ public class DOMAST extends ViewPart {
|
||||||
*/
|
*/
|
||||||
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
|
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private TreeItem expandTreeToTreeObject(TreeItem[] treeItems, TreeObject treeObj) {
|
||||||
|
for (int i=0; i<treeItems.length; i++) {
|
||||||
|
if (treeItems[i].getData() == treeObj) {
|
||||||
|
return treeItems[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
TreeParent parent = treeObj.getParent();
|
||||||
|
|
||||||
|
if (parent == null) return null;
|
||||||
|
|
||||||
|
while (parent != treeItems[i].getData()) {
|
||||||
|
parent = parent.getParent();
|
||||||
|
if (parent == null) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parent == treeItems[i].getData()) {
|
||||||
|
treeItems[i].setExpanded(true);
|
||||||
|
viewer.refresh();
|
||||||
|
|
||||||
|
return expandTreeToTreeObject(treeItems[i].getItems(), treeObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null; // nothing found
|
||||||
|
}
|
||||||
|
|
||||||
|
private TreeItem expandTreeToTreeObject(TreeObject treeObj) {
|
||||||
|
return expandTreeToTreeObject(viewer.getTree().getItems(), treeObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find an ASTNode in the tree and expand the tree to that node.
|
||||||
|
* Returns true if successful, false otherwise.
|
||||||
|
*
|
||||||
|
* @param offset
|
||||||
|
* @param findString
|
||||||
|
* @param searchForward
|
||||||
|
* @param caseSensitive
|
||||||
|
* @param wholeWord
|
||||||
|
* @param regExSearch
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean findAndSelect(IASTNode node, boolean useOffset) {
|
||||||
|
// get the TreeObject from the AST View's model corresponding to the IASTNode
|
||||||
|
TreeObject treeNode = null;
|
||||||
|
TreeItem treeItem = null;
|
||||||
|
|
||||||
|
treeNode = getTUTreeParent().findTreeObject(node, useOffset);
|
||||||
|
|
||||||
|
if (treeNode != null && treeNode.getParent() != null) {
|
||||||
|
// found a matching TreeObject, so expand the tree to that object
|
||||||
|
treeItem = expandTreeToTreeObject(treeNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// select the node that was found (and is now displayed)
|
||||||
|
if (treeItem != null) {
|
||||||
|
TreeItem[] items = new TreeItem[1];
|
||||||
|
items[0] = treeItem;
|
||||||
|
treeItem.getParent().setSelection(items);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ViewLabelProvider extends LabelProvider {
|
class ViewLabelProvider extends LabelProvider {
|
||||||
|
@ -559,7 +621,10 @@ public class DOMAST extends ViewPart {
|
||||||
|
|
||||||
public void setContentProvider(ViewContentProvider vcp) {
|
public void setContentProvider(ViewContentProvider vcp) {
|
||||||
viewer.setContentProvider(vcp);
|
viewer.setContentProvider(vcp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IContentProvider getContentProvider() {
|
||||||
|
return viewer.getContentProvider();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void hookContextMenu() {
|
private void hookContextMenu() {
|
||||||
|
@ -628,35 +693,7 @@ public class DOMAST extends ViewPart {
|
||||||
private void makeActions() {
|
private void makeActions() {
|
||||||
loadActiveEditorAction = new Action() {
|
loadActiveEditorAction = new Action() {
|
||||||
public void run() {
|
public void run() {
|
||||||
// get the active editor
|
openDOMASTView(getActiveEditor());
|
||||||
IEditorPart editor = getActiveEditor();
|
|
||||||
if (editor instanceof CEditor) {
|
|
||||||
IViewPart tempView = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
tempView = getSite().getPage().showView(OpenDOMViewAction.VIEW_ID);
|
|
||||||
} catch (PartInitException pie) {}
|
|
||||||
|
|
||||||
if (tempView != null) {
|
|
||||||
if (tempView instanceof DOMAST) {
|
|
||||||
IFile aFile = ((CEditor)editor).getInputFile();
|
|
||||||
|
|
||||||
// check if the file is a valid "compilation unit" (based on file extension)
|
|
||||||
String ext = aFile.getFileExtension().toUpperCase();
|
|
||||||
if (!(ext.equals(EXTENSION_C) || ext.equals(EXTENSION_CC) || ext.equals(EXTENSION_CPP) || ext.equals(EXTENSION_CXX))) {
|
|
||||||
showMessage(NOT_VALID_COMPILATION_UNIT);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
((DOMAST)tempView).setFile(aFile);
|
|
||||||
((DOMAST)tempView).setPart(editor);
|
|
||||||
((DOMAST)tempView).setLang(getLanguageFromFile(aFile));
|
|
||||||
((DOMAST)tempView).setContentProvider(((DOMAST)tempView).new ViewContentProvider(((CEditor)editor).getInputFile()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getSite().getPage().activate(tempView);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
loadActiveEditorAction.setText(LOAD_ACTIVE_EDITOR);
|
loadActiveEditorAction.setText(LOAD_ACTIVE_EDITOR);
|
||||||
|
@ -748,17 +785,6 @@ public class DOMAST extends ViewPart {
|
||||||
return editor;
|
return editor;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ParserLanguage getLanguageFromFile(IFile file) {
|
|
||||||
IProject project = file.getProject();
|
|
||||||
ICFileType type = CCorePlugin.getDefault().getFileType(project, file.getFullPath().lastSegment());
|
|
||||||
String lid = type.getLanguage().getId();
|
|
||||||
if ( lid != null && lid.equals(ICFileTypeConstants.LANG_CXX) ) {
|
|
||||||
return ParserLanguage.CPP;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ParserLanguage.C;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ASTHighlighterAction extends Action {
|
private class ASTHighlighterAction extends Action {
|
||||||
IEditorPart aPart = null;
|
IEditorPart aPart = null;
|
||||||
|
|
||||||
|
@ -913,4 +939,105 @@ public class DOMAST extends ViewPart {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class RunAfterViewOpenJob extends Job {
|
||||||
|
|
||||||
|
Runnable runner = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public RunAfterViewOpenJob(String name, Runnable runner) {
|
||||||
|
super(name);
|
||||||
|
this.runner = runner;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
|
||||||
|
*/
|
||||||
|
protected IStatus run(IProgressMonitor monitor) {
|
||||||
|
try {
|
||||||
|
initializeASTViewJob.join();
|
||||||
|
CTestPlugin.getStandardDisplay().asyncExec(runner);
|
||||||
|
} catch (InterruptedException ie) {}
|
||||||
|
|
||||||
|
return Status.OK_STATUS;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open the DOM AST View and return a reference to it. This helper method can also be used to run an
|
||||||
|
* Action after the DOM AST View has been fully loaded (like find/select nodes in the view).
|
||||||
|
*
|
||||||
|
* Note: The action is not guaranteed to run. An example would be if loading the view is canceled.
|
||||||
|
*
|
||||||
|
* @param editor
|
||||||
|
* @param action
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static IViewPart openDOMASTViewRunAction(IEditorPart editor, Runnable runnable, String nameOfJob) {
|
||||||
|
IViewPart view = openDOMASTView(editor);
|
||||||
|
|
||||||
|
if (view == null) return null;
|
||||||
|
|
||||||
|
RunAfterViewOpenJob job = ((DOMAST)view).new RunAfterViewOpenJob(nameOfJob, runnable);
|
||||||
|
job.schedule();
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open the DOM AST View and return a reference to it.
|
||||||
|
*
|
||||||
|
* @param editor
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static IViewPart openDOMASTView(IEditorPart editor) {
|
||||||
|
IWorkbenchPartSite site = editor.getSite();
|
||||||
|
Shell shell = site.getShell();
|
||||||
|
IViewPart tempView = null;
|
||||||
|
|
||||||
|
// get the active editor
|
||||||
|
if (editor instanceof CEditor) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
tempView = site.getPage().showView(OpenDOMViewAction.VIEW_ID);
|
||||||
|
} catch (PartInitException pie) {}
|
||||||
|
|
||||||
|
if (tempView != null) {
|
||||||
|
if (tempView instanceof DOMAST) {
|
||||||
|
IFile aFile = ((CEditor)editor).getInputFile();
|
||||||
|
|
||||||
|
// check if the file is a valid "compilation unit" (based on file extension)
|
||||||
|
String ext = aFile.getFileExtension().toUpperCase();
|
||||||
|
if (!(ext.equals(EXTENSION_C) || ext.equals(EXTENSION_CC) || ext.equals(EXTENSION_CPP) || ext.equals(EXTENSION_CXX))) {
|
||||||
|
MessageDialog.openInformation(shell, DOMAST.VIEW_NAME, NOT_VALID_COMPILATION_UNIT);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
((DOMAST)tempView).setFile(aFile);
|
||||||
|
((DOMAST)tempView).setPart(editor);
|
||||||
|
((DOMAST)tempView).setLang(getLanguageFromFile(aFile));
|
||||||
|
((DOMAST)tempView).setContentProvider(((DOMAST)tempView).new ViewContentProvider(((CEditor)editor).getInputFile()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
site.getPage().activate(tempView);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return tempView;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ParserLanguage getLanguageFromFile(IFile file) {
|
||||||
|
IProject project = file.getProject();
|
||||||
|
ICFileType type = CCorePlugin.getDefault().getFileType(project, file.getFullPath().lastSegment());
|
||||||
|
String lid = type.getLanguage().getId();
|
||||||
|
if ( lid != null && lid.equals(ICFileTypeConstants.LANG_CXX) ) {
|
||||||
|
return ParserLanguage.CPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ParserLanguage.C;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -11,6 +11,7 @@
|
||||||
package org.eclipse.cdt.ui.tests.DOMAST;
|
package org.eclipse.cdt.ui.tests.DOMAST;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
@ -401,11 +402,11 @@ public class FindIASTNameTarget implements IFindReplaceTarget, IFindReplaceTarge
|
||||||
// get the TreeObject from the AST View's model corresponding to that name
|
// get the TreeObject from the AST View's model corresponding to that name
|
||||||
TreeObject treeNode = null;
|
TreeObject treeNode = null;
|
||||||
TreeItem treeItem = null;
|
TreeItem treeItem = null;
|
||||||
treeNode = tuTreeParent.findTreeObjectForIASTName(foundName);
|
treeNode = tuTreeParent.findTreeObject(foundName, true, true);
|
||||||
|
|
||||||
if (treeNode != null && treeNode.getParent() != null) {
|
if (treeNode != null && treeNode.getParent() != null) {
|
||||||
// found a matching TreeObject, so expand the tree to that object
|
// found a matching TreeObject, so expand the tree to that object
|
||||||
treeItem = expandTreeToTreeObject(treeNode); // TODO Devin test this
|
treeItem = expandTreeToTreeObject(treeNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// loop until the next name within the matchingNames list is found in the tree
|
// loop until the next name within the matchingNames list is found in the tree
|
||||||
|
@ -413,11 +414,11 @@ public class FindIASTNameTarget implements IFindReplaceTarget, IFindReplaceTarge
|
||||||
((searchForward && index < matchingNames.length) ||
|
((searchForward && index < matchingNames.length) ||
|
||||||
(!searchForward && index >= 0))) {
|
(!searchForward && index >= 0))) {
|
||||||
foundName = findNextMatchingName( findString, searchForward, caseSensitive, wholeWord, regExSearch );
|
foundName = findNextMatchingName( findString, searchForward, caseSensitive, wholeWord, regExSearch );
|
||||||
treeNode = tuTreeParent.findTreeObjectForIASTName(foundName);
|
treeNode = tuTreeParent.findTreeObject(foundName, true, true);
|
||||||
|
|
||||||
if (treeNode != null && treeNode.getParent() != null) {
|
if (treeNode != null && treeNode.getParent() != null) {
|
||||||
// found a matching TreeObject, so expand the tree to that object
|
// found a matching TreeObject, so expand the tree to that object
|
||||||
treeItem = expandTreeToTreeObject(treeNode); // TODO Devin test this
|
treeItem = expandTreeToTreeObject(treeNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,173 @@
|
||||||
|
/**********************************************************************
|
||||||
|
* Copyright (c) 2005 IBM Canada and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Common Public License v0.5
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/cpl-v05.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Rational Software - Initial API and implementation
|
||||||
|
**********************************************************************/
|
||||||
|
package org.eclipse.cdt.ui.tests.DOMAST;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||||
|
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.IASTTranslationUnit;
|
||||||
|
import org.eclipse.cdt.internal.ui.editor.CEditor;
|
||||||
|
import org.eclipse.cdt.internal.ui.util.ExternalEditorInput;
|
||||||
|
import org.eclipse.cdt.ui.testplugin.CTestPlugin;
|
||||||
|
import org.eclipse.core.resources.IFile;
|
||||||
|
import org.eclipse.core.resources.IStorage;
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
import org.eclipse.jface.action.IAction;
|
||||||
|
import org.eclipse.jface.dialogs.MessageDialog;
|
||||||
|
import org.eclipse.jface.text.TextSelection;
|
||||||
|
import org.eclipse.jface.viewers.IContentProvider;
|
||||||
|
import org.eclipse.swt.widgets.Event;
|
||||||
|
import org.eclipse.ui.IEditorActionDelegate;
|
||||||
|
import org.eclipse.ui.IEditorInput;
|
||||||
|
import org.eclipse.ui.IEditorPart;
|
||||||
|
import org.eclipse.ui.IViewPart;
|
||||||
|
import org.eclipse.ui.PartInitException;
|
||||||
|
import org.eclipse.ui.actions.ActionDelegate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dsteffle
|
||||||
|
*/
|
||||||
|
public class ShowInDOMViewAction extends ActionDelegate implements
|
||||||
|
IEditorActionDelegate {
|
||||||
|
|
||||||
|
CEditor editor = null;
|
||||||
|
IASTTranslationUnit tu = null;
|
||||||
|
IViewPart view = null;
|
||||||
|
String file = null;
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.ui.IEditorActionDelegate#setActiveEditor(org.eclipse.jface.action.IAction, org.eclipse.ui.IEditorPart)
|
||||||
|
*/
|
||||||
|
public void setActiveEditor(IAction action, IEditorPart targetEditor) {
|
||||||
|
if (targetEditor instanceof CEditor)
|
||||||
|
editor = (CEditor)targetEditor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.ui.actions.ActionDelegate#runWithEvent(org.eclipse.jface.action.IAction, org.eclipse.swt.widgets.Event)
|
||||||
|
*/
|
||||||
|
public void runWithEvent(IAction action, Event event) {
|
||||||
|
TextSelection selection = null;
|
||||||
|
|
||||||
|
if (editor != null &&
|
||||||
|
editor.getSelectionProvider().getSelection() instanceof TextSelection) {
|
||||||
|
selection = (TextSelection)editor.getSelectionProvider().getSelection();
|
||||||
|
}
|
||||||
|
if (selection != null) {
|
||||||
|
if (!isFileInView()) {
|
||||||
|
view = DOMAST.openDOMASTViewRunAction(editor, new FindDisplayNode(selection.getOffset(), selection.getLength()), "Find Node in AST DOM View");
|
||||||
|
} else {
|
||||||
|
new FindDisplayNode(selection.getOffset(), selection.getLength()).run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showMessage(String message) {
|
||||||
|
MessageDialog.openInformation(CTestPlugin.getStandardDisplay().getActiveShell(), DOMAST.VIEW_NAME, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isFileInView() {
|
||||||
|
if( editor.getInputFile() != null )
|
||||||
|
file = editor.getInputFile().getLocation().toOSString();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( editor.getEditorInput() instanceof ExternalEditorInput )
|
||||||
|
file = ((ExternalEditorInput)editor.getEditorInput()).getStorage().getFullPath().toOSString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file == null) return false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
view = editor.getSite().getPage().showView(OpenDOMViewAction.VIEW_ID);
|
||||||
|
} catch (PartInitException pie) {}
|
||||||
|
|
||||||
|
if (view != null) {
|
||||||
|
if (view instanceof DOMAST) {
|
||||||
|
IContentProvider provider = ((DOMAST)view).getContentProvider();
|
||||||
|
if (provider != null && provider instanceof DOMAST.ViewContentProvider) {
|
||||||
|
tu = ((DOMAST.ViewContentProvider)provider).getTU();
|
||||||
|
|
||||||
|
if (tu != null) {
|
||||||
|
String fileName = null;
|
||||||
|
|
||||||
|
// check if file is tu
|
||||||
|
IASTNodeLocation[] locs = tu.getNodeLocations();
|
||||||
|
for (int i=0; i<locs.length; i++) {
|
||||||
|
if (locs[i] instanceof IASTFileLocation) {
|
||||||
|
fileName = ((IASTFileLocation)locs[i]).getFileName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileName == null) return false;
|
||||||
|
|
||||||
|
if (fileName.equals(file) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check the #includes on the TU (i.e. check if selecting something from a header file shown in DOM View)
|
||||||
|
IASTPreprocessorIncludeStatement[] includes = tu.getIncludeDirectives();
|
||||||
|
for(int i=0; i<includes.length; i++) {
|
||||||
|
if (includes[i].getPath().equals(file)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return false; // not a valid editor
|
||||||
|
}
|
||||||
|
|
||||||
|
private class FindDisplayNode implements Runnable {
|
||||||
|
private static final String IASTNode_NOT_FOUND = "IASTNode not found for the selection. Try refreshing the AST View if changes were made to the source.";
|
||||||
|
int offset = 0;
|
||||||
|
int length = 0;
|
||||||
|
|
||||||
|
public FindDisplayNode(int offset, int length) {
|
||||||
|
this.offset = offset;
|
||||||
|
this.length = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.action.Action#run()
|
||||||
|
*/
|
||||||
|
public void run() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
if (view instanceof DOMAST) {
|
||||||
|
IContentProvider provider = ((DOMAST)view).getContentProvider();
|
||||||
|
if (provider != null && provider instanceof DOMAST.ViewContentProvider) {
|
||||||
|
tu = ((DOMAST.ViewContentProvider)provider).getTU();
|
||||||
|
if( editor.getInputFile() != null )
|
||||||
|
file = editor.getInputFile().getLocation().toOSString();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( editor.getEditorInput() instanceof ExternalEditorInput )
|
||||||
|
file = ((ExternalEditorInput)editor.getEditorInput()).getStorage().getFullPath().toOSString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// the selection is within a file currently shown in the DOM AST View
|
||||||
|
if (tu != null && file != null && view instanceof DOMAST) {
|
||||||
|
IASTNode node = tu.selectNodeForLocation(file, offset, length);
|
||||||
|
if (node != null && ((DOMAST)view).getContentProvider() instanceof DOMAST.ViewContentProvider) {
|
||||||
|
((DOMAST.ViewContentProvider)((DOMAST)view).getContentProvider()).findAndSelect(node, true); // use offsets when searching for node equality
|
||||||
|
} else {
|
||||||
|
showMessage(IASTNode_NOT_FOUND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -15,6 +15,7 @@ import java.util.Iterator;
|
||||||
|
|
||||||
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.internal.core.dom.parser.ASTNode;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -127,14 +128,14 @@ public class TreeParent extends TreeObject {
|
||||||
* @param node
|
* @param node
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private TreeParent findTreeObject(TreeObject[] trees, IASTNode node) {
|
private TreeParent findTreeObject(TreeObject[] trees, IASTNode node, boolean useOffset, boolean useName) {
|
||||||
for (int i=0; i<trees.length; i++) {
|
for (int i=0; i<trees.length; i++) {
|
||||||
|
|
||||||
if (trees[i] != null && trees[i] instanceof TreeParent) {
|
if (trees[i] != null && trees[i] instanceof TreeParent) {
|
||||||
if ( ((TreeParent)trees[i]).getNode() == node ) {
|
if ( equalNodes( ((TreeParent)trees[i]).getNode(), node, useOffset, useName ) ) {
|
||||||
return (TreeParent)trees[i];
|
return (TreeParent)trees[i];
|
||||||
} else if ( ((TreeParent)trees[i]).hasChildren() ){
|
} else if ( ((TreeParent)trees[i]).hasChildren() ){
|
||||||
TreeParent tree = findTreeObject( ((TreeParent)trees[i]).getChildren(), node );
|
TreeParent tree = findTreeObject( ((TreeParent)trees[i]).getChildren(), node, useOffset, useName );
|
||||||
if (tree != null) return tree;
|
if (tree != null) return tree;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,42 +151,32 @@ public class TreeParent extends TreeObject {
|
||||||
* @param node
|
* @param node
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public TreeParent findTreeObject(IASTNode node) {
|
public TreeParent findTreeObject(IASTNode node, boolean useOffset) {
|
||||||
|
return findTreeObject(node, useOffset, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the TreeParent that corresponds to the IASTNode. This is the TreeParent
|
||||||
|
* that represents the IASTNode in the DOM AST View.
|
||||||
|
*
|
||||||
|
* @param node
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public TreeParent findTreeObject(IASTNode node, boolean useOffset, boolean useName) {
|
||||||
if (node == null) return null;
|
if (node == null) return null;
|
||||||
|
|
||||||
Iterator itr = children.iterator();
|
Iterator itr = children.iterator();
|
||||||
while (itr.hasNext()) {
|
while (itr.hasNext()) {
|
||||||
Object o = itr.next();
|
Object o = itr.next();
|
||||||
if (o != null && o instanceof TreeParent) {
|
if (o != null && o instanceof TreeParent) {
|
||||||
if ( ((TreeParent)o).getNode() == node ) {
|
IASTNode treeNode = ((TreeParent)o).getNode();
|
||||||
|
|
||||||
|
if (equalNodes(node, ((TreeParent)o).getNode(), useOffset, useName))
|
||||||
return (TreeParent)o;
|
return (TreeParent)o;
|
||||||
} else if ( ((TreeParent)o).hasChildren() ){
|
|
||||||
TreeParent tree = findTreeObject( ((TreeParent)o).getChildren(), node );
|
|
||||||
if (tree != null) return tree;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null; // nothing found
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the TreeParent that corresponds to the IASTName. This is based on string and offset equality.
|
|
||||||
*
|
|
||||||
* @param node
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public TreeParent findTreeObjectForIASTName(IASTName name) {
|
|
||||||
if (name == null) return null;
|
|
||||||
|
|
||||||
Iterator itr = children.iterator();
|
|
||||||
while (itr.hasNext()) {
|
|
||||||
Object o = itr.next();
|
|
||||||
if (o != null && o instanceof TreeParent) {
|
|
||||||
if (treeParentHasName((TreeParent)o, name)) return (TreeParent)o;
|
|
||||||
|
|
||||||
|
// search the children
|
||||||
if ( ((TreeParent)o).hasChildren() ){
|
if ( ((TreeParent)o).hasChildren() ){
|
||||||
TreeParent tree = findTreeObjectForIASTName( ((TreeParent)o).getChildren(), name );
|
TreeParent tree = findTreeObject( ((TreeParent)o).getChildren(), node, useOffset, useName );
|
||||||
if (tree != null) return tree;
|
if (tree != null) return tree;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,38 +185,30 @@ public class TreeParent extends TreeObject {
|
||||||
return null; // nothing found
|
return null; // nothing found
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private boolean equalNodes(IASTNode node1, IASTNode node2, boolean useOffset, boolean useName) {
|
||||||
* Returns the TreeParent that corresponds to the IASTName. This is based on string and offset equality.
|
if (useName &&
|
||||||
*
|
(!(node1 instanceof IASTName) || !(node2 instanceof IASTName) ||
|
||||||
* @param trees
|
!(((IASTName)node1).toString().equals(((IASTName)node2).toString())))) return false;
|
||||||
* @param node
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private TreeParent findTreeObjectForIASTName(TreeObject[] trees, IASTName name) {
|
|
||||||
for (int i=0; i<trees.length; i++) {
|
|
||||||
|
|
||||||
if (trees[i] != null && trees[i] instanceof TreeParent) {
|
if (useOffset) {
|
||||||
if (treeParentHasName((TreeParent)trees[i], name)) return (TreeParent)trees[i];
|
if (node1 instanceof ASTNode && node2 instanceof ASTNode) {
|
||||||
|
if (((ASTNode)node1).getOffset() == ((ASTNode)node2).getOffset() &&
|
||||||
if ( ((TreeParent)trees[i]).hasChildren() ){
|
((ASTNode)node1).getLength() == ((ASTNode)node2).getLength())
|
||||||
TreeParent tree = findTreeObjectForIASTName( ((TreeParent)trees[i]).getChildren(), name );
|
return true;
|
||||||
if (tree != null) return tree;
|
} else {
|
||||||
|
IASTNodeLocation[] locs1 = node1.getNodeLocations();
|
||||||
|
IASTNodeLocation[] locs2 = node2.getNodeLocations();
|
||||||
|
for(int i=0; i<locs1.length && i<locs2.length; i++) {
|
||||||
|
if (locs1[i].getNodeOffset() != locs2[i].getNodeOffset() ||
|
||||||
|
locs1[i].getNodeLength() != locs2[i].getNodeLength())
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null; // nothing found
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean treeParentHasName(TreeParent tp, IASTName name) {
|
|
||||||
if ( tp.getNode() instanceof IASTName &&
|
|
||||||
tp.getNode() instanceof ASTNode &&
|
|
||||||
name instanceof ASTNode) {
|
|
||||||
IASTName treeName = (IASTName)tp.getNode();
|
|
||||||
ASTNode treeNode = (ASTNode)tp.getNode();
|
|
||||||
if (treeName.toString().equals(name.toString()) && treeNode.getOffset() == ((ASTNode)name).getOffset() ) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if ( node1 == node2 )
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Add table
Reference in a new issue