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:
parent
2ce7d65442
commit
c7e0b78046
15 changed files with 459 additions and 223 deletions
|
@ -11,9 +11,12 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.ui.refactoring;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.eclipse.osgi.util.NLS;
|
||||
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.IASTDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
||||
|
@ -38,17 +41,28 @@ public class AddDeclarationNodeToClassChange {
|
|||
|
||||
private final ICPPASTCompositeTypeSpecifier nodeClass;
|
||||
private final VisibilityEnum visibility;
|
||||
private final IASTNode fieldNodes;
|
||||
private ArrayList<IASTNode> fieldNodes = new ArrayList<IASTNode>();
|
||||
private final ModificationCollector collector;
|
||||
|
||||
public static void createChange(ICPPASTCompositeTypeSpecifier nodeClass, VisibilityEnum visibility, IASTNode fieldNodes, boolean isField, ModificationCollector collector) {
|
||||
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) {
|
||||
this.nodeClass = nodeClass;
|
||||
this.visibility = visibility;
|
||||
this.fieldNodes = fieldNodes;
|
||||
this.fieldNodes.add(fieldNodes);
|
||||
this.collector = collector;
|
||||
createRewrites(isField);
|
||||
}
|
||||
|
@ -58,8 +72,10 @@ public class AddDeclarationNodeToClassChange {
|
|||
int lastFieldDeclaration = -1;
|
||||
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;
|
||||
if(IASTCompositeTypeSpecifier.k_struct == nodeClass.getKey()) {
|
||||
currentVisibility = VisibilityEnum.v_public;
|
||||
}
|
||||
|
||||
// Find the insert location by iterating over the elements of the class
|
||||
// and remembering the last element with the matching visibility
|
||||
|
@ -119,7 +135,9 @@ public class AddDeclarationNodeToClassChange {
|
|||
|
||||
private void insertBefore(IASTNode nearestNode) {
|
||||
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) {
|
||||
|
@ -131,7 +149,9 @@ public class AddDeclarationNodeToClassChange {
|
|||
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() {
|
||||
|
|
|
@ -11,16 +11,14 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.ui.refactoring;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.OperationCanceledException;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.core.runtime.SubMonitor;
|
||||
import org.eclipse.jface.text.ITextSelection;
|
||||
import org.eclipse.jface.text.Region;
|
||||
import org.eclipse.jface.viewers.ISelection;
|
||||
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.IASTDeclaration;
|
||||
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.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTProblem;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTProblemDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTProblemExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTProblemStatement;
|
||||
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.IASTTranslationUnit;
|
||||
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.index.IIndex;
|
||||
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.IASTDeclarationAmbiguity;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.refactoring.utils.SelectionHelper;
|
||||
|
||||
/**
|
||||
* The baseclass for all other refactorings, provides some common implementations for
|
||||
* condition checking, change generating, selection handling and translation unit loading.
|
||||
|
@ -97,7 +90,7 @@ public abstract class CRefactoring extends Refactoring {
|
|||
}
|
||||
else {
|
||||
this.file = file;
|
||||
this.region = getRegion(selection);
|
||||
this.region = SelectionHelper.getRegion(selection);
|
||||
}
|
||||
|
||||
this.initStatus=new RefactoringStatus();
|
||||
|
@ -270,14 +263,6 @@ public abstract class CRefactoring extends Refactoring {
|
|||
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,
|
||||
IProgressMonitor mon) {
|
||||
SubMonitor subMonitor = SubMonitor.convert(mon, 10);
|
||||
|
@ -312,116 +297,6 @@ public abstract class CRefactoring extends Refactoring {
|
|||
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() {
|
||||
ProblemFinder pf = new ProblemFinder(initStatus);
|
||||
unit.accept(pf);
|
||||
|
@ -434,16 +309,6 @@ public abstract class CRefactoring extends Refactoring {
|
|||
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 {
|
||||
if (fIndex == null) {
|
||||
ICProject[] projects= CoreModel.getDefault().getCModel().getCProjects();
|
||||
|
@ -462,4 +327,26 @@ public abstract class CRefactoring extends Refactoring {
|
|||
public IIndex getIndex() {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.ModificationCollector;
|
||||
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;
|
||||
|
||||
/**
|
||||
|
@ -218,7 +220,7 @@ public class ExtractConstantRefactoring extends CRefactoring {
|
|||
private boolean isOneMarked(Collection<IASTLiteralExpression> literalExpressionVector, Region textSelection) {
|
||||
boolean oneMarked = false;
|
||||
for (IASTLiteralExpression expression : literalExpressionVector) {
|
||||
boolean isInSameFileSelection = isInSameFileSelection(textSelection, expression);
|
||||
boolean isInSameFileSelection = SelectionHelper.isInSameFileSelection(textSelection, expression, file);
|
||||
if(isInSameFileSelection){
|
||||
if(target == null) {
|
||||
target = expression;
|
||||
|
@ -259,13 +261,13 @@ public class ExtractConstantRefactoring extends CRefactoring {
|
|||
protected void collectModifications(IProgressMonitor pm, ModificationCollector collector)
|
||||
throws CoreException, OperationCanceledException {
|
||||
|
||||
MethodContext context = findContext(target);
|
||||
MethodContext context = NodeHelper.findMethodContext(target);
|
||||
Collection<IASTExpression> locLiteralsToReplace = new ArrayList<IASTExpression>();
|
||||
|
||||
if(context.getType() == MethodContext.ContextType.METHOD){
|
||||
|
||||
for (IASTExpression expression : literalsToReplace) {
|
||||
MethodContext exprContext = findContext(expression);
|
||||
MethodContext exprContext = NodeHelper.findMethodContext(expression);
|
||||
if(exprContext.getType() == MethodContext.ContextType.METHOD){
|
||||
if( MethodContext.isSameClass(exprContext.getMethodQName(), context.getMethodQName())){
|
||||
locLiteralsToReplace.add(expression);
|
||||
|
|
|
@ -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.utils.ASTHelper;
|
||||
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 {
|
||||
|
||||
|
@ -187,7 +189,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
}
|
||||
|
||||
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);
|
||||
sm.done();
|
||||
return status;
|
||||
|
@ -244,7 +246,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
|
||||
final IASTName astMethodName = new CPPASTName(info.getMethodName()
|
||||
.toCharArray());
|
||||
MethodContext context = findContext(container.getNodesToWrite().get(0));
|
||||
MethodContext context = NodeHelper.findMethodContext(container.getNodesToWrite().get(0));
|
||||
|
||||
if (context.getType() == ContextType.METHOD) {
|
||||
ICPPASTCompositeTypeSpecifier classDeclaration = (ICPPASTCompositeTypeSpecifier) context
|
||||
|
@ -273,7 +275,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
final IASTName astMethodName = new CPPASTName(info.getMethodName()
|
||||
.toCharArray());
|
||||
|
||||
MethodContext context = findContext(container.getNodesToWrite().get(0));
|
||||
MethodContext context = NodeHelper.findMethodContext(container.getNodesToWrite().get(0));
|
||||
|
||||
// Create Declaration in Class
|
||||
if (context.getType() == ContextType.METHOD) {
|
||||
|
@ -781,7 +783,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
private IASTNode getReturnAssignment(IASTExpressionStatement stmt,
|
||||
IASTFunctionCallExpression callExpression, IASTName retname) {
|
||||
if (info.getReturnVariable().equals(info.getInScopeDeclaredVariable())) {
|
||||
IASTSimpleDeclaration orgDecl = findSimpleDeclarationInParents(info
|
||||
IASTSimpleDeclaration orgDecl = NodeHelper.findSimpleDeclarationInParents(info
|
||||
.getReturnVariable().getDeclaration());
|
||||
IASTSimpleDeclaration decl = new CPPASTSimpleDeclaration();
|
||||
|
||||
|
@ -848,7 +850,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
@Override
|
||||
public int visit(IASTStatement stmt) {
|
||||
if (!(stmt instanceof IASTCompoundStatement)
|
||||
&& isSelectedFile(region, stmt)) {
|
||||
&& SelectionHelper.isSelectedFile(region, stmt, file)) {
|
||||
container.add(stmt);
|
||||
return PROCESS_SKIP;
|
||||
}
|
||||
|
@ -857,7 +859,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
|
||||
@Override
|
||||
public int visit(IASTExpression expression) {
|
||||
if (isSelectedFile(region, expression)) {
|
||||
if (SelectionHelper.isSelectedFile(region, expression, file)) {
|
||||
container.add(expression);
|
||||
return PROCESS_SKIP;
|
||||
}
|
||||
|
|
|
@ -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.CRefactoring;
|
||||
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;
|
||||
|
||||
/**
|
||||
|
@ -84,7 +85,7 @@ public class GenerateGettersAndSettersRefactoring extends CRefactoring {
|
|||
if ((declarators[0] instanceof IASTFunctionDeclarator)) {
|
||||
context.existingFunctionDeclarations.add(fieldDeclaration);
|
||||
} else {
|
||||
if(isInSameFile(fieldDeclaration)){
|
||||
if(SelectionHelper.isInSameFile(fieldDeclaration, file)){
|
||||
context.existingFields.add(fieldDeclaration);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.ICPPASTCompositeTypeSpecifier;
|
||||
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.model.ICElement;
|
||||
|
||||
|
@ -101,29 +100,6 @@ public class HideMethodRefactoring extends CRefactoring {
|
|||
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) {
|
||||
while(fieldToFoundDecl != null){
|
||||
if (fieldToFoundDecl instanceof IASTSimpleDeclaration) {
|
||||
|
|
|
@ -131,7 +131,7 @@ public class ImplementMethodRefactoring extends CRefactoring {
|
|||
if (!insertLocation.hasFile()) {
|
||||
insertLocation.setInsertFile(file);
|
||||
insertLocation.setNodeToInsertAfter(NodeHelper
|
||||
.getTopLevelParent(methodDeclaration));
|
||||
.findTopLevelParent(methodDeclaration));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -78,10 +78,10 @@ public class DefinitionFinder {
|
|||
} else {
|
||||
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>();
|
||||
transUnit.accept(new CPPASTVisitor() {
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -15,12 +15,13 @@ import java.util.regex.Pattern;
|
|||
|
||||
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.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
|
||||
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;
|
||||
|
||||
|
@ -37,7 +38,15 @@ public class NameHelper {
|
|||
|
||||
public static boolean isValidLocalVariableName(String name) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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){
|
||||
char[] letters = fieldName.toCharArray();
|
||||
int start = 0;
|
||||
|
@ -131,4 +112,12 @@ public class NameHelper {
|
|||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -11,17 +11,30 @@
|
|||
*******************************************************************************/
|
||||
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.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.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.ICPPASTQualifiedName;
|
||||
|
||||
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.ui.refactoring.MethodContext;
|
||||
|
||||
/**
|
||||
* General class for common Node operations.
|
||||
*
|
||||
* @author Lukas Felber
|
||||
* @author Lukas Felber & Guido Zgraggen
|
||||
*
|
||||
*/
|
||||
public class NodeHelper {
|
||||
|
@ -54,10 +67,95 @@ public class NodeHelper {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static IASTNode getTopLevelParent(IASTNode currentNode) {
|
||||
public static IASTNode findTopLevelParent(IASTNode currentNode) {
|
||||
while(currentNode != null && currentNode.getParent() != null && currentNode.getParent().getParent() != null) {
|
||||
return getTopLevelParent(currentNode.getParent());
|
||||
return findTopLevelParent(currentNode.getParent());
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,24 +11,41 @@
|
|||
*******************************************************************************/
|
||||
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.viewers.ISelection;
|
||||
|
||||
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.IASTTranslationUnit;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Helper class to suport operations conserning a selection.
|
||||
*
|
||||
* @author Mirko Stocker
|
||||
* @author Mirko Stocker, Lukas Felber
|
||||
*
|
||||
*/
|
||||
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) {
|
||||
|
||||
final Container<IASTSimpleDeclaration> container = new Container<IASTSimpleDeclaration>();
|
||||
|
@ -39,7 +56,7 @@ public class SelectionHelper {
|
|||
}
|
||||
@Override
|
||||
public int visit(IASTDeclaration declaration) {
|
||||
if (declaration instanceof IASTSimpleDeclaration && CRefactoring.isSelectionOnExpression(textSelection, declaration)) {
|
||||
if (declaration instanceof IASTSimpleDeclaration && isSelectionOnExpression(textSelection, declaration)) {
|
||||
container.setObject((IASTSimpleDeclaration) declaration);
|
||||
}
|
||||
return super.visit(declaration);
|
||||
|
@ -48,4 +65,68 @@ public class SelectionHelper {
|
|||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue