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

Separates refactoring base from utilities by Emanuel Graf, bug 232260.

This commit is contained in:
Markus Schorn 2008-05-15 14:25:22 +00:00
parent 2ce7d65442
commit c7e0b78046
15 changed files with 459 additions and 223 deletions

View file

@ -11,9 +11,12 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring; package org.eclipse.cdt.internal.ui.refactoring;
import java.util.ArrayList;
import org.eclipse.osgi.util.NLS; import org.eclipse.osgi.util.NLS;
import org.eclipse.text.edits.TextEditGroup; import org.eclipse.text.edits.TextEditGroup;
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
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.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
@ -38,17 +41,28 @@ public class AddDeclarationNodeToClassChange {
private final ICPPASTCompositeTypeSpecifier nodeClass; private final ICPPASTCompositeTypeSpecifier nodeClass;
private final VisibilityEnum visibility; private final VisibilityEnum visibility;
private final IASTNode fieldNodes; private ArrayList<IASTNode> fieldNodes = new ArrayList<IASTNode>();
private final ModificationCollector collector; private final ModificationCollector collector;
public static void createChange(ICPPASTCompositeTypeSpecifier nodeClass, VisibilityEnum visibility, IASTNode fieldNodes, boolean isField, ModificationCollector collector) { public static void createChange(ICPPASTCompositeTypeSpecifier nodeClass, VisibilityEnum visibility, IASTNode fieldNodes, boolean isField, ModificationCollector collector) {
new AddDeclarationNodeToClassChange(nodeClass, visibility, fieldNodes, collector, isField); new AddDeclarationNodeToClassChange(nodeClass, visibility, fieldNodes, collector, isField);
} }
public static void createChange(ICPPASTCompositeTypeSpecifier nodeClass, VisibilityEnum visibility, ArrayList<IASTNode> fieldNodes, boolean isField, ModificationCollector collector) {
new AddDeclarationNodeToClassChange(nodeClass, visibility, fieldNodes, collector, isField);
}
private AddDeclarationNodeToClassChange(ICPPASTCompositeTypeSpecifier nodeClass, VisibilityEnum visibility, ArrayList<IASTNode> fieldNodes, ModificationCollector collector, boolean isField) {
this.fieldNodes = fieldNodes;
this.nodeClass = nodeClass;
this.visibility = visibility;
this.collector = collector;
createRewrites(isField);
}
private AddDeclarationNodeToClassChange(ICPPASTCompositeTypeSpecifier nodeClass, VisibilityEnum visibility, IASTNode fieldNodes, ModificationCollector collector, boolean isField) { private AddDeclarationNodeToClassChange(ICPPASTCompositeTypeSpecifier nodeClass, VisibilityEnum visibility, IASTNode fieldNodes, ModificationCollector collector, boolean isField) {
this.nodeClass = nodeClass; this.nodeClass = nodeClass;
this.visibility = visibility; this.visibility = visibility;
this.fieldNodes = fieldNodes; this.fieldNodes.add(fieldNodes);
this.collector = collector; this.collector = collector;
createRewrites(isField); createRewrites(isField);
} }
@ -58,8 +72,10 @@ public class AddDeclarationNodeToClassChange {
int lastFieldDeclaration = -1; int lastFieldDeclaration = -1;
IASTDeclaration[] members = nodeClass.getMembers(); IASTDeclaration[] members = nodeClass.getMembers();
// XXX Don't we have to differentiate between the default visibility in a class and a struct?
VisibilityEnum currentVisibility = VisibilityEnum.v_private; VisibilityEnum currentVisibility = VisibilityEnum.v_private;
if(IASTCompositeTypeSpecifier.k_struct == nodeClass.getKey()) {
currentVisibility = VisibilityEnum.v_public;
}
// Find the insert location by iterating over the elements of the class // Find the insert location by iterating over the elements of the class
// and remembering the last element with the matching visibility // and remembering the last element with the matching visibility
@ -119,7 +135,9 @@ public class AddDeclarationNodeToClassChange {
private void insertBefore(IASTNode nearestNode) { private void insertBefore(IASTNode nearestNode) {
ASTRewrite rewrite = collector.rewriterForTranslationUnit(nearestNode.getTranslationUnit()); ASTRewrite rewrite = collector.rewriterForTranslationUnit(nearestNode.getTranslationUnit());
rewrite.insertBefore(nearestNode.getParent(), nearestNode, fieldNodes, createEditDescription()); for(IASTNode node: fieldNodes) {
rewrite.insertBefore(nearestNode.getParent(), nearestNode, node, createEditDescription());
}
} }
private void insertAtTheEnd(VisibilityEnum currentVisibility) { private void insertAtTheEnd(VisibilityEnum currentVisibility) {
@ -131,7 +149,9 @@ public class AddDeclarationNodeToClassChange {
rewrite.insertBefore(nodeClass, null, label, createEditDescription()); rewrite.insertBefore(nodeClass, null, label, createEditDescription());
} }
rewrite.insertBefore(nodeClass, null, fieldNodes, createEditDescription()); for(IASTNode node: fieldNodes) {
rewrite.insertBefore(nodeClass, null, node, createEditDescription());
}
} }
private TextEditGroup createEditDescription() { private TextEditGroup createEditDescription() {

View file

@ -11,16 +11,14 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring; package org.eclipse.cdt.internal.ui.refactoring;
import java.util.Vector;
import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SubMonitor; import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.Region; import org.eclipse.jface.text.Region;
import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ltk.core.refactoring.Change; import org.eclipse.ltk.core.refactoring.Change;
@ -31,23 +29,16 @@ import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTMacroExpansionLocation;
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.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTProblem; import org.eclipse.cdt.core.dom.ast.IASTProblem;
import org.eclipse.cdt.core.dom.ast.IASTProblemDeclaration; import org.eclipse.cdt.core.dom.ast.IASTProblemDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTProblemExpression; import org.eclipse.cdt.core.dom.ast.IASTProblemExpression;
import org.eclipse.cdt.core.dom.ast.IASTProblemStatement; import org.eclipse.cdt.core.dom.ast.IASTProblemStatement;
import org.eclipse.cdt.core.dom.ast.IASTProblemTypeId; import org.eclipse.cdt.core.dom.ast.IASTProblemTypeId;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTStatement; 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.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.CModelException;
@ -63,6 +54,8 @@ import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousExpression;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousStatement; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousStatement;
import org.eclipse.cdt.internal.core.dom.parser.IASTDeclarationAmbiguity; import org.eclipse.cdt.internal.core.dom.parser.IASTDeclarationAmbiguity;
import org.eclipse.cdt.internal.ui.refactoring.utils.SelectionHelper;
/** /**
* The baseclass for all other refactorings, provides some common implementations for * The baseclass for all other refactorings, provides some common implementations for
* condition checking, change generating, selection handling and translation unit loading. * condition checking, change generating, selection handling and translation unit loading.
@ -97,7 +90,7 @@ public abstract class CRefactoring extends Refactoring {
} }
else { else {
this.file = file; this.file = file;
this.region = getRegion(selection); this.region = SelectionHelper.getRegion(selection);
} }
this.initStatus=new RefactoringStatus(); this.initStatus=new RefactoringStatus();
@ -270,14 +263,6 @@ public abstract class CRefactoring extends Refactoring {
return name; return name;
} }
private Region getRegion(ISelection selection) {
if (selection instanceof ITextSelection) {
final ITextSelection txtSelection= (ITextSelection) selection;
return new Region(txtSelection.getOffset(), txtSelection.getLength());
}
return null;
}
protected boolean loadTranslationUnit(RefactoringStatus status, protected boolean loadTranslationUnit(RefactoringStatus status,
IProgressMonitor mon) { IProgressMonitor mon) {
SubMonitor subMonitor = SubMonitor.convert(mon, 10); SubMonitor subMonitor = SubMonitor.convert(mon, 10);
@ -312,116 +297,6 @@ public abstract class CRefactoring extends Refactoring {
return tu.getAST(fIndex, AST_STYLE); return tu.getAST(fIndex, AST_STYLE);
} }
private static class ExpressionPosition {
public int start;
public int end;
@Override
public String toString() {
return String.format("Position ranges from %d to %d and has a length of %d", Integer.valueOf(start), //$NON-NLS-1$
Integer.valueOf(end), Integer.valueOf(end - start));
}
}
protected static ExpressionPosition createExpressionPosition(IASTNode expression) {
ExpressionPosition selection = new ExpressionPosition();
int nodeLength = 0;
IASTNodeLocation[] nodeLocations = expression.getNodeLocations();
if (nodeLocations.length != 1) {
for (IASTNodeLocation location : nodeLocations) {
if (location instanceof IASTMacroExpansionLocation) {
IASTMacroExpansionLocation macroLoc = (IASTMacroExpansionLocation) location;
selection.start = macroLoc.asFileLocation().getNodeOffset();
nodeLength = macroLoc.asFileLocation().getNodeLength();
}
}
} else {
if (nodeLocations[0] instanceof IASTMacroExpansionLocation) {
IASTMacroExpansionLocation macroLoc = (IASTMacroExpansionLocation) nodeLocations[0];
selection.start = macroLoc.asFileLocation().getNodeOffset();
nodeLength = macroLoc.asFileLocation().getNodeLength();
} else {
IASTFileLocation loc = expression.getFileLocation();
selection.start = loc.getNodeOffset();
nodeLength = loc.getNodeLength();
}
}
selection.end = selection.start + nodeLength;
return selection;
}
protected boolean isExpressionWhollyInSelection(Region textSelection, IASTNode expression) {
ExpressionPosition exprPos = createExpressionPosition(expression);
int selStart = textSelection.getOffset();
int selEnd = textSelection.getLength() + selStart;
return exprPos.start >= selStart && exprPos.end <= selEnd;
}
public static boolean isSelectionOnExpression(Region textSelection, IASTNode expression) {
ExpressionPosition exprPos = createExpressionPosition(expression);
int selStart = textSelection.getOffset();
int selEnd = textSelection.getLength() + selStart;
return exprPos.end > selStart && exprPos.start < selEnd;
}
protected boolean isInSameFile(IASTNode node) {
IPath path = new Path(node.getContainingFilename());
IFile locFile = ResourcesPlugin.getWorkspace().getRoot().getFile(file.getLocation());
IFile tmpFile = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
return locFile.equals(tmpFile);
}
protected boolean isInSameFileSelection(Region textSelection, IASTNode node) {
if( isInSameFile(node) ) {
return isSelectionOnExpression(textSelection, node);
}
return false;
}
protected boolean isSelectedFile(Region textSelection, IASTNode node) {
if( isInSameFile(node) ) {
return isExpressionWhollyInSelection(textSelection, node);
}
return false;
}
protected MethodContext findContext(IASTNode node) {
boolean found = false;
MethodContext context = new MethodContext();
context.setType(MethodContext.ContextType.NONE);
IASTName name = null;
while(node != null && !found){
node = node.getParent();
if(node instanceof IASTFunctionDeclarator){
name=((IASTFunctionDeclarator)node).getName();
found = true;
context.setType(MethodContext.ContextType.FUNCTION);
} else if (node instanceof IASTFunctionDefinition){
name=((IASTFunctionDefinition)node).getDeclarator().getName();
found = true;
context.setType(MethodContext.ContextType.FUNCTION);
}
}
if(name instanceof ICPPASTQualifiedName){
ICPPASTQualifiedName qname =( ICPPASTQualifiedName )name;
context.setMethodQName(qname);
IBinding bind = qname.resolveBinding();
IASTName[] decl = unit.getDeclarationsInAST(bind);//TODO HSR funktioniert nur fuer namen aus der aktuellen Translationunit
for (IASTName tmpname : decl) {
IASTNode methoddefinition = tmpname.getParent().getParent();
if (methoddefinition instanceof IASTSimpleDeclaration) {
context.setMethodDeclarationName(tmpname);
context.setType(MethodContext.ContextType.METHOD);
}
}
}
return context;
}
protected boolean translationUnitHasProblem() { protected boolean translationUnitHasProblem() {
ProblemFinder pf = new ProblemFinder(initStatus); ProblemFinder pf = new ProblemFinder(initStatus);
unit.accept(pf); unit.accept(pf);
@ -434,16 +309,6 @@ public abstract class CRefactoring extends Refactoring {
return af.ambiguityFound(); return af.ambiguityFound();
} }
protected IASTSimpleDeclaration findSimpleDeclarationInParents(IASTNode node) {
while(node != null){
if (node instanceof IASTSimpleDeclaration) {
return (IASTSimpleDeclaration) node;
}
node = node.getParent();
}
return null;
}
public void lockIndex() throws CoreException, InterruptedException { public void lockIndex() throws CoreException, InterruptedException {
if (fIndex == null) { if (fIndex == null) {
ICProject[] projects= CoreModel.getDefault().getCModel().getCProjects(); ICProject[] projects= CoreModel.getDefault().getCModel().getCProjects();
@ -462,4 +327,26 @@ public abstract class CRefactoring extends Refactoring {
public IIndex getIndex() { public IIndex getIndex() {
return fIndex; return fIndex;
} }
protected Vector<IASTName> findAllMarkedNames() {
final Vector<IASTName> namesVector = new Vector<IASTName>();
unit.accept(new CPPASTVisitor() {
{
shouldVisitNames = true;
}
@Override
public int visit(IASTName name) {
if (SelectionHelper.isInSameFileSelection(region, name, file)) {
if (!(name instanceof ICPPASTQualifiedName)) {
namesVector.add(name);
}
}
return super.visit(name);
}
});
return namesVector;
}
} }

View file

@ -64,6 +64,8 @@ import org.eclipse.cdt.internal.ui.refactoring.CRefactoring;
import org.eclipse.cdt.internal.ui.refactoring.MethodContext; import org.eclipse.cdt.internal.ui.refactoring.MethodContext;
import org.eclipse.cdt.internal.ui.refactoring.ModificationCollector; import org.eclipse.cdt.internal.ui.refactoring.ModificationCollector;
import org.eclipse.cdt.internal.ui.refactoring.NameNVisibilityInformation; import org.eclipse.cdt.internal.ui.refactoring.NameNVisibilityInformation;
import org.eclipse.cdt.internal.ui.refactoring.utils.NodeHelper;
import org.eclipse.cdt.internal.ui.refactoring.utils.SelectionHelper;
import org.eclipse.cdt.internal.ui.refactoring.utils.TranslationUnitHelper; import org.eclipse.cdt.internal.ui.refactoring.utils.TranslationUnitHelper;
/** /**
@ -218,7 +220,7 @@ public class ExtractConstantRefactoring extends CRefactoring {
private boolean isOneMarked(Collection<IASTLiteralExpression> literalExpressionVector, Region textSelection) { private boolean isOneMarked(Collection<IASTLiteralExpression> literalExpressionVector, Region textSelection) {
boolean oneMarked = false; boolean oneMarked = false;
for (IASTLiteralExpression expression : literalExpressionVector) { for (IASTLiteralExpression expression : literalExpressionVector) {
boolean isInSameFileSelection = isInSameFileSelection(textSelection, expression); boolean isInSameFileSelection = SelectionHelper.isInSameFileSelection(textSelection, expression, file);
if(isInSameFileSelection){ if(isInSameFileSelection){
if(target == null) { if(target == null) {
target = expression; target = expression;
@ -259,13 +261,13 @@ public class ExtractConstantRefactoring extends CRefactoring {
protected void collectModifications(IProgressMonitor pm, ModificationCollector collector) protected void collectModifications(IProgressMonitor pm, ModificationCollector collector)
throws CoreException, OperationCanceledException { throws CoreException, OperationCanceledException {
MethodContext context = findContext(target); MethodContext context = NodeHelper.findMethodContext(target);
Collection<IASTExpression> locLiteralsToReplace = new ArrayList<IASTExpression>(); Collection<IASTExpression> locLiteralsToReplace = new ArrayList<IASTExpression>();
if(context.getType() == MethodContext.ContextType.METHOD){ if(context.getType() == MethodContext.ContextType.METHOD){
for (IASTExpression expression : literalsToReplace) { for (IASTExpression expression : literalsToReplace) {
MethodContext exprContext = findContext(expression); MethodContext exprContext = NodeHelper.findMethodContext(expression);
if(exprContext.getType() == MethodContext.ContextType.METHOD){ if(exprContext.getType() == MethodContext.ContextType.METHOD){
if( MethodContext.isSameClass(exprContext.getMethodQName(), context.getMethodQName())){ if( MethodContext.isSameClass(exprContext.getMethodQName(), context.getMethodQName())){
locLiteralsToReplace.add(expression); locLiteralsToReplace.add(expression);

View file

@ -98,6 +98,8 @@ import org.eclipse.cdt.internal.ui.refactoring.MethodContext.ContextType;
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer.NameInformation; import org.eclipse.cdt.internal.ui.refactoring.NodeContainer.NameInformation;
import org.eclipse.cdt.internal.ui.refactoring.utils.ASTHelper; import org.eclipse.cdt.internal.ui.refactoring.utils.ASTHelper;
import org.eclipse.cdt.internal.ui.refactoring.utils.CPPASTAllVisitor; import org.eclipse.cdt.internal.ui.refactoring.utils.CPPASTAllVisitor;
import org.eclipse.cdt.internal.ui.refactoring.utils.NodeHelper;
import org.eclipse.cdt.internal.ui.refactoring.utils.SelectionHelper;
public class ExtractFunctionRefactoring extends CRefactoring { public class ExtractFunctionRefactoring extends CRefactoring {
@ -187,7 +189,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
} }
info.setDeclarator(getDeclaration(container.getNodesToWrite().get(0))); info.setDeclarator(getDeclaration(container.getNodesToWrite().get(0)));
MethodContext context = findContext(container.getNodesToWrite().get(0)); MethodContext context = NodeHelper.findMethodContext(container.getNodesToWrite().get(0));
info.setMethodContext(context); info.setMethodContext(context);
sm.done(); sm.done();
return status; return status;
@ -244,7 +246,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
final IASTName astMethodName = new CPPASTName(info.getMethodName() final IASTName astMethodName = new CPPASTName(info.getMethodName()
.toCharArray()); .toCharArray());
MethodContext context = findContext(container.getNodesToWrite().get(0)); MethodContext context = NodeHelper.findMethodContext(container.getNodesToWrite().get(0));
if (context.getType() == ContextType.METHOD) { if (context.getType() == ContextType.METHOD) {
ICPPASTCompositeTypeSpecifier classDeclaration = (ICPPASTCompositeTypeSpecifier) context ICPPASTCompositeTypeSpecifier classDeclaration = (ICPPASTCompositeTypeSpecifier) context
@ -273,7 +275,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
final IASTName astMethodName = new CPPASTName(info.getMethodName() final IASTName astMethodName = new CPPASTName(info.getMethodName()
.toCharArray()); .toCharArray());
MethodContext context = findContext(container.getNodesToWrite().get(0)); MethodContext context = NodeHelper.findMethodContext(container.getNodesToWrite().get(0));
// Create Declaration in Class // Create Declaration in Class
if (context.getType() == ContextType.METHOD) { if (context.getType() == ContextType.METHOD) {
@ -781,7 +783,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
private IASTNode getReturnAssignment(IASTExpressionStatement stmt, private IASTNode getReturnAssignment(IASTExpressionStatement stmt,
IASTFunctionCallExpression callExpression, IASTName retname) { IASTFunctionCallExpression callExpression, IASTName retname) {
if (info.getReturnVariable().equals(info.getInScopeDeclaredVariable())) { if (info.getReturnVariable().equals(info.getInScopeDeclaredVariable())) {
IASTSimpleDeclaration orgDecl = findSimpleDeclarationInParents(info IASTSimpleDeclaration orgDecl = NodeHelper.findSimpleDeclarationInParents(info
.getReturnVariable().getDeclaration()); .getReturnVariable().getDeclaration());
IASTSimpleDeclaration decl = new CPPASTSimpleDeclaration(); IASTSimpleDeclaration decl = new CPPASTSimpleDeclaration();
@ -848,7 +850,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
@Override @Override
public int visit(IASTStatement stmt) { public int visit(IASTStatement stmt) {
if (!(stmt instanceof IASTCompoundStatement) if (!(stmt instanceof IASTCompoundStatement)
&& isSelectedFile(region, stmt)) { && SelectionHelper.isSelectedFile(region, stmt, file)) {
container.add(stmt); container.add(stmt);
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@ -857,7 +859,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
@Override @Override
public int visit(IASTExpression expression) { public int visit(IASTExpression expression) {
if (isSelectedFile(region, expression)) { if (SelectionHelper.isSelectedFile(region, expression, file)) {
container.add(expression); container.add(expression);
return PROCESS_SKIP; return PROCESS_SKIP;
} }

View file

@ -32,6 +32,7 @@ import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.internal.ui.refactoring.AddDeclarationNodeToClassChange; import org.eclipse.cdt.internal.ui.refactoring.AddDeclarationNodeToClassChange;
import org.eclipse.cdt.internal.ui.refactoring.CRefactoring; import org.eclipse.cdt.internal.ui.refactoring.CRefactoring;
import org.eclipse.cdt.internal.ui.refactoring.ModificationCollector; import org.eclipse.cdt.internal.ui.refactoring.ModificationCollector;
import org.eclipse.cdt.internal.ui.refactoring.utils.SelectionHelper;
import org.eclipse.cdt.internal.ui.refactoring.utils.VisibilityEnum; import org.eclipse.cdt.internal.ui.refactoring.utils.VisibilityEnum;
/** /**
@ -84,7 +85,7 @@ public class GenerateGettersAndSettersRefactoring extends CRefactoring {
if ((declarators[0] instanceof IASTFunctionDeclarator)) { if ((declarators[0] instanceof IASTFunctionDeclarator)) {
context.existingFunctionDeclarations.add(fieldDeclaration); context.existingFunctionDeclarations.add(fieldDeclaration);
} else { } else {
if(isInSameFile(fieldDeclaration)){ if(SelectionHelper.isInSameFile(fieldDeclaration, file)){
context.existingFields.add(fieldDeclaration); context.existingFields.add(fieldDeclaration);
} }
} }

View file

@ -31,7 +31,6 @@ import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor; import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite; import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElement;
@ -101,29 +100,6 @@ public class HideMethodRefactoring extends CRefactoring {
return initStatus; return initStatus;
} }
private Vector<IASTName> findAllMarkedNames() {
final Vector<IASTName> namesVector = new Vector<IASTName>();
unit.accept(new CPPASTVisitor(){
{
shouldVisitNames = true;
}
@Override
public int visit(IASTName name) {
if( isInSameFileSelection(region, name) ) {
if (!(name instanceof ICPPASTQualifiedName)) {
namesVector.add(name);
}
}
return super.visit(name);
}
});
return namesVector;
}
protected IASTSimpleDeclaration findSimpleDeclaration(IASTNode fieldToFoundDecl) { protected IASTSimpleDeclaration findSimpleDeclaration(IASTNode fieldToFoundDecl) {
while(fieldToFoundDecl != null){ while(fieldToFoundDecl != null){
if (fieldToFoundDecl instanceof IASTSimpleDeclaration) { if (fieldToFoundDecl instanceof IASTSimpleDeclaration) {

View file

@ -131,7 +131,7 @@ public class ImplementMethodRefactoring extends CRefactoring {
if (!insertLocation.hasFile()) { if (!insertLocation.hasFile()) {
insertLocation.setInsertFile(file); insertLocation.setInsertFile(file);
insertLocation.setNodeToInsertAfter(NodeHelper insertLocation.setNodeToInsertAfter(NodeHelper
.getTopLevelParent(methodDeclaration)); .findTopLevelParent(methodDeclaration));
} }
} }

View file

@ -0,0 +1,74 @@
/*******************************************************************************
* Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Institute for Software - initial API and implementation
******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.utils;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Path;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.internal.ui.refactoring.Container;
/**
* @author Guido Zgraggen IFS
*/
public class DeclarationFinder {
public static DeclarationFinderDO getDeclaration(IASTName name, IIndex index) throws CoreException {
IIndexBinding binding = index.findBinding(name);
IIndexName[] pdomref = index.findDeclarations(binding);
IIndexName[] allNamesPDom = index.findNames(binding, IIndex.FIND_REFERENCES);
if (pdomref == null || pdomref.length < 1) {
return null;
}
String filename2 = pdomref[0].getFileLocation().getFileName();
IASTTranslationUnit transUnit = TranslationUnitHelper.loadTranslationUnit(filename2);
IASTName declName = DeclarationFinder.findDeclarationInTranslationUnit(transUnit, pdomref[0]);
return new DeclarationFinderDO(allNamesPDom, transUnit, filename2, declName);
}
public static IASTName findDeclarationInTranslationUnit(IASTTranslationUnit transUnit, final IIndexName indexName) {
final Container<IASTName> defName = new Container<IASTName>();
transUnit.accept(new CPPASTVisitor() {
{
shouldVisitNames = true;
}
@Override
public int visit(IASTName name) {
if (name.isDeclaration() && name.getNodeLocations().length > 0) {
IASTNodeLocation nodeLocation = name.getNodeLocations()[0];
if (indexName.getNodeOffset() == nodeLocation.getNodeOffset()
&& indexName.getNodeLength() == nodeLocation.getNodeLength()
&& new Path(indexName.getFileLocation().getFileName()).equals(new Path(nodeLocation.asFileLocation().getFileName()))) {
defName.setObject(name);
return ASTVisitor.PROCESS_ABORT;
}
}
return ASTVisitor.PROCESS_CONTINUE;
}
});
return defName.getObject();
}
}

View file

@ -0,0 +1,34 @@
/*******************************************************************************
* Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Institute for Software - initial API and implementation
******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.utils;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.index.IIndexName;
/**
* @author Guido Zgraggen IFS
*
*/
public class DeclarationFinderDO {
public IASTTranslationUnit transUnit = null;
public String filename = null;
public IIndexName[] allNamesPDom = null;
public IASTName name = null;
public DeclarationFinderDO(IIndexName[] allNamesPDom2, IASTTranslationUnit transUnit2, String filename2, IASTName name2) {
this.transUnit = transUnit2;
this.filename = filename2;
this.allNamesPDom = allNamesPDom2;
this.name = name2;
}
}

View file

@ -78,10 +78,10 @@ public class DefinitionFinder {
} else { } else {
transUnit = parsedFiles.get(pdomref[0].getFileLocation().getFileName()); transUnit = parsedFiles.get(pdomref[0].getFileLocation().getFileName());
} }
return findDefinitionInTranslationUnit(transUnit, methodName, pdomref[0]); return findDefinitionInTranslationUnit(transUnit, pdomref[0]);
} }
private static IASTName findDefinitionInTranslationUnit(IASTTranslationUnit transUnit, final IASTName name2, final IIndexName indexName) { private static IASTName findDefinitionInTranslationUnit(IASTTranslationUnit transUnit, final IIndexName indexName) {
final Container<IASTName> defName = new Container<IASTName>(); final Container<IASTName> defName = new Container<IASTName>();
transUnit.accept(new CPPASTVisitor() { transUnit.accept(new CPPASTVisitor() {
{ {

View file

@ -0,0 +1,54 @@
/*******************************************************************************
* Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Institute for Software - initial API and implementation
******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.utils;
import org.eclipse.core.runtime.Path;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.internal.ui.refactoring.Container;
/**
* @author Guido Zgraggen IFS
*/
public class ExpressionFinder {
public static IASTName findExpressionInTranslationUnit(IASTTranslationUnit transUnit, final IIndexName indexName) {
final Container<IASTName> expName = new Container<IASTName>();
transUnit.accept(new CPPASTVisitor() {
{
shouldVisitNames = true;
}
@Override
public int visit(IASTName name) {
if (name.isReference() && name.getNodeLocations().length > 0) {
IASTNodeLocation nodeLocation = name.getNodeLocations()[0];
if (indexName.getNodeOffset() == nodeLocation.getNodeOffset()
&& indexName.getNodeLength() == nodeLocation.getNodeLength()
&& new Path(indexName.getFileLocation().getFileName()).equals(new Path(nodeLocation.asFileLocation().getFileName()))) {
expName.setObject(name);
return ASTVisitor.PROCESS_ABORT;
}
}
return ASTVisitor.PROCESS_CONTINUE;
}
});
return expName.getObject();
}
}

View file

@ -15,12 +15,13 @@ import java.util.regex.Pattern;
import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFile;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
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.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.parser.Keywords;
import org.eclipse.cdt.core.parser.util.CharArrayIntMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTQualifiedName; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTQualifiedName;
@ -37,7 +38,15 @@ public class NameHelper {
public static boolean isValidLocalVariableName(String name) { public static boolean isValidLocalVariableName(String name) {
boolean valid = Pattern.compile(localVariableRegexp).matcher(name).matches(); boolean valid = Pattern.compile(localVariableRegexp).matcher(name).matches();
return valid; /* && Keyword.getKeyword(stringToValidate, stringToValidate.length()) == null*/ //TODO Check for keywords?; return valid;
}
public static boolean isKeyword(String name) {
CharArrayIntMap keywords = new CharArrayIntMap(0, -1);
Keywords.addKeywordsC(keywords);
Keywords.addKeywordsCpp(keywords);
Keywords.addKeywordsPreprocessor(keywords);
return keywords.containsKey(name.toCharArray());
} }
/** /**
@ -69,34 +78,6 @@ public class NameHelper {
return qname; return qname;
} }
public static IASTFunctionDefinition getAncestorFunctionDefinition(IASTName startNode) {
return (IASTFunctionDefinition) getAncestorDefinition(startNode, IASTFunctionDefinition.class);
}
public static IASTSimpleDeclaration getAncestorFunctionDeclaration(IASTName startNode) {
return (IASTSimpleDeclaration) getAncestorDefinition(startNode, IASTSimpleDeclaration.class);
}
public static ICPPASTCompositeTypeSpecifier getAncestorClassDefinition(IASTName startNode) {
return (ICPPASTCompositeTypeSpecifier) getAncestorDefinition(startNode, ICPPASTCompositeTypeSpecifier.class);
}
public static IASTNode getAncestorDefinition(IASTName startNode, Class<? extends IASTNode> type) {
IASTNode node = startNode;
while(node != null ){
if(type.isInstance(node)) {
return node;
}
node = node.getParent();
}
return null;
}
public static String trimFieldName(String fieldName){ public static String trimFieldName(String fieldName){
char[] letters = fieldName.toCharArray(); char[] letters = fieldName.toCharArray();
int start = 0; int start = 0;
@ -129,6 +110,14 @@ public class NameHelper {
name = Character.toUpperCase(name.charAt(0)) + name.substring(1); name = Character.toUpperCase(name.charAt(0)) + name.substring(1);
} }
return name; return name;
} }
public static String getTypeName(IASTParameterDeclaration parameter) {
IASTDeclSpecifier parameterDeclSpecifier = parameter.getDeclSpecifier();
if (parameterDeclSpecifier instanceof ICPPASTNamedTypeSpecifier) {
return ((ICPPASTNamedTypeSpecifier) parameterDeclSpecifier).getName().getRawSignature();
} else {
return parameterDeclSpecifier.getRawSignature();
}
}
} }

View file

@ -0,0 +1,18 @@
package org.eclipse.cdt.internal.ui.refactoring.utils;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTDeclarator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNamedTypeSpecifier;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTParameterDeclaration;
public class NodeFactory {
public static IASTParameterDeclaration createParameterDeclaration(String paramType, String paramName) {
CPPASTNamedTypeSpecifier type = new CPPASTNamedTypeSpecifier(new CPPASTName(paramType.toCharArray()), false);
CPPASTDeclarator declarator = new CPPASTDeclarator(new CPPASTName(paramName.toCharArray()));
return new CPPASTParameterDeclaration(type,declarator);
}
}

View file

@ -11,17 +11,30 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.utils; package org.eclipse.cdt.internal.ui.refactoring.utils;
import org.eclipse.core.runtime.Path;
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
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.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNamespaceDefinition; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNamespaceDefinition;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTranslationUnit; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTranslationUnit;
import org.eclipse.cdt.internal.ui.refactoring.MethodContext;
/** /**
* General class for common Node operations. * General class for common Node operations.
* *
* @author Lukas Felber * @author Lukas Felber & Guido Zgraggen
* *
*/ */
public class NodeHelper { public class NodeHelper {
@ -54,10 +67,95 @@ public class NodeHelper {
return null; return null;
} }
public static IASTNode getTopLevelParent(IASTNode currentNode) { public static IASTNode findTopLevelParent(IASTNode currentNode) {
while(currentNode != null && currentNode.getParent() != null && currentNode.getParent().getParent() != null) { while(currentNode != null && currentNode.getParent() != null && currentNode.getParent().getParent() != null) {
return getTopLevelParent(currentNode.getParent()); return findTopLevelParent(currentNode.getParent());
} }
return currentNode; return currentNode;
} }
public static boolean isSameNode(IASTNode node1, IASTNode node2) {
if(node1 == null || node2 == null) {
return false;
}
return node1.getNodeLocations()[0].getNodeOffset() == node2.getNodeLocations()[0].getNodeOffset()
&& node1.getNodeLocations()[0].getNodeLength() == node2.getNodeLocations()[0].getNodeLength()
&& new Path(node1.getFileLocation().getFileName()).equals(new Path(node2.getFileLocation().getFileName()));
}
public static IASTSimpleDeclaration findSimpleDeclarationInParents(IASTNode node) {
while(node != null){
if (node instanceof IASTSimpleDeclaration) {
return (IASTSimpleDeclaration) node;
}
node = node.getParent();
}
return null;
}
public static MethodContext findMethodContext(IASTNode node) {
IASTTranslationUnit translationUnit = node.getTranslationUnit();
boolean found = false;
MethodContext context = new MethodContext();
context.setType(MethodContext.ContextType.NONE);
IASTName name = null;
while(node != null && !found){
node = node.getParent();
if(node instanceof IASTFunctionDeclarator){
name=((IASTFunctionDeclarator)node).getName();
found = true;
context.setType(MethodContext.ContextType.FUNCTION);
} else if (node instanceof IASTFunctionDefinition){
name=((IASTFunctionDefinition)node).getDeclarator().getName();
found = true;
context.setType(MethodContext.ContextType.FUNCTION);
}
}
if(name instanceof ICPPASTQualifiedName){
ICPPASTQualifiedName qname =( ICPPASTQualifiedName )name;
context.setMethodQName(qname);
IBinding bind = qname.resolveBinding();
IASTName[] decl = translationUnit.getDeclarationsInAST(bind);//TODO HSR works only for names in the current translationUnit
for (IASTName tmpname : decl) {
IASTNode methoddefinition = tmpname.getParent().getParent();
if (methoddefinition instanceof IASTSimpleDeclaration) {
context.setMethodDeclarationName(tmpname);
context.setType(MethodContext.ContextType.METHOD);
}
}
}
return context;
}
public static IASTCompoundStatement findCompoundStatementInParent(IASTNode node) {
while(node != null){
if (node instanceof IASTCompoundStatement) {
return (IASTCompoundStatement) node;
}
node = node.getParent();
}
return null;
}
public static IASTCompositeTypeSpecifier findEnclosingClass(IASTNode node) {
while(!(node instanceof IASTCompositeTypeSpecifier)){
if(node instanceof IASTTranslationUnit) {
return null;
}
node = node.getParent();
}
return (IASTCompositeTypeSpecifier) node;
}
public static IASTFunctionDefinition findFunctionDefinition(IASTNode node) {
while(node != null){
if (node instanceof IASTFunctionDefinition) {
return (IASTFunctionDefinition) node;
}
node = node.getParent();
}
return null;
}
} }

View file

@ -11,24 +11,41 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.utils; package org.eclipse.cdt.internal.ui.refactoring.utils;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.Region; import org.eclipse.jface.text.Region;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTMacroExpansionLocation;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor; import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
import org.eclipse.cdt.internal.ui.refactoring.CRefactoring;
import org.eclipse.cdt.internal.ui.refactoring.Container; import org.eclipse.cdt.internal.ui.refactoring.Container;
/** /**
* Helper class to suport operations conserning a selection. * Helper class to suport operations conserning a selection.
* *
* @author Mirko Stocker * @author Mirko Stocker, Lukas Felber
* *
*/ */
public class SelectionHelper { public class SelectionHelper {
public static Region getRegion(ISelection selection) {
if (selection instanceof ITextSelection) {
final ITextSelection txtSelection= (ITextSelection) selection;
return new Region(txtSelection.getOffset(), txtSelection.getLength());
}
return null;
}
public static IASTSimpleDeclaration findFirstSelectedDeclaration(final Region textSelection, IASTTranslationUnit translationUnit) { public static IASTSimpleDeclaration findFirstSelectedDeclaration(final Region textSelection, IASTTranslationUnit translationUnit) {
final Container<IASTSimpleDeclaration> container = new Container<IASTSimpleDeclaration>(); final Container<IASTSimpleDeclaration> container = new Container<IASTSimpleDeclaration>();
@ -39,7 +56,7 @@ public class SelectionHelper {
} }
@Override @Override
public int visit(IASTDeclaration declaration) { public int visit(IASTDeclaration declaration) {
if (declaration instanceof IASTSimpleDeclaration && CRefactoring.isSelectionOnExpression(textSelection, declaration)) { if (declaration instanceof IASTSimpleDeclaration && isSelectionOnExpression(textSelection, declaration)) {
container.setObject((IASTSimpleDeclaration) declaration); container.setObject((IASTSimpleDeclaration) declaration);
} }
return super.visit(declaration); return super.visit(declaration);
@ -48,4 +65,68 @@ public class SelectionHelper {
return container.getObject(); return container.getObject();
} }
public static boolean isSelectionOnExpression(Region textSelection, IASTNode expression) {
Region exprPos = createExpressionPosition(expression);
int selStart = textSelection.getOffset();
int selEnd = textSelection.getLength() + selStart;
return exprPos.getOffset()+exprPos.getLength() > selStart && exprPos.getOffset() < selEnd;
}
public static boolean isExpressionWhollyInSelection(Region textSelection, IASTNode expression) {
Region exprPos = createExpressionPosition(expression);
int selStart = textSelection.getOffset();
int selEnd = textSelection.getLength() + selStart;
return exprPos.getOffset() >= selStart && exprPos.getOffset()+exprPos.getLength() <= selEnd;
}
public static boolean isInSameFile(IASTNode node, IFile file) {
IPath path = new Path(node.getContainingFilename());
IFile locFile = ResourcesPlugin.getWorkspace().getRoot().getFile(file.getLocation());
IFile tmpFile = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
return locFile.equals(tmpFile);
}
public static boolean isInSameFileSelection(Region textSelection, IASTNode node, IFile file) {
if( isInSameFile(node, file) ) {
return SelectionHelper.isSelectionOnExpression(textSelection, node);
}
return false;
}
public static boolean isSelectedFile(Region textSelection, IASTNode node, IFile file) {
if( isInSameFile(node, file) ) {
return isExpressionWhollyInSelection(textSelection, node);
}
return false;
}
protected static Region createExpressionPosition(IASTNode expression) {
int start = 0;
int nodeLength = 0;
IASTNodeLocation[] nodeLocations = expression.getNodeLocations();
if (nodeLocations.length != 1) {
for (IASTNodeLocation location : nodeLocations) {
if (location instanceof IASTMacroExpansionLocation) {
IASTMacroExpansionLocation macroLoc = (IASTMacroExpansionLocation) location;
start = macroLoc.asFileLocation().getNodeOffset();
nodeLength = macroLoc.asFileLocation().getNodeLength();
}
}
} else {
if (nodeLocations[0] instanceof IASTMacroExpansionLocation) {
IASTMacroExpansionLocation macroLoc = (IASTMacroExpansionLocation) nodeLocations[0];
start = macroLoc.asFileLocation().getNodeOffset();
nodeLength = macroLoc.asFileLocation().getNodeLength();
} else {
IASTFileLocation loc = expression.getFileLocation();
start = loc.getNodeOffset();
nodeLength = loc.getNodeLength();
}
}
return new Region(start, nodeLength);
}
} }