When I am writing code I include trace calls at the start of every method which looks like this:
public void doOperation()
{
Trace tr = new Trace("doOperation");
... method body ...
}
I am trying to write an Eclipse plugin so that when I rename a method the string constant in the trace method call is also updated. To achieve this I am implementing a RenameParticipant.
The issue I have is that the Change I produce only works correctly when the method name doesn't change length. If the method name changes length then my change ends up editing the wrong offset within the changed file.
What am I doing wrong? How can I account for the fact that the method rename may alter the offset within the file of my Trace call?
-----
To compute the Change I use the following code:
@Override
public Change createChange(IProgressMonitor pm)
throws CoreException,
OperationCanceledException
{
ICompilationUnit unit = element.getCompilationUnit();
CompilationUnit astCompUnit = parse(unit, pm);
ASTNode astElement = NodeFinder.perform(astCompUnit, element.getNameRange());
MethodDeclaration astMethod = (MethodDeclaration)getParent(astElement, MethodDeclaration.class);
String newName = getArguments().getNewName();
List<TraceFnFixOperation> ops = new ArrayList<TraceFnFixOperation>(1);
TraceFnCtorFinder finder = new TraceFnCtorFinder(newName, ops);
astMethod.accept(finder);
if (ops.size() == 0)
return null;
return new TraceChange("Fix Trace", unit, ops);
}
The body of the TraceFnCtorFinder:
public static class TraceFnCtorFinder extends ASTVisitor
{
private final String methodName;
private final List<TraceFnFixOperation> workingops;
public TraceFnCtorFinder(String methodName, List<TraceFnFixOperation> workingops)
{
this.methodName = methodName;
this.workingops = workingops;
}
@Override
public boolean visit(ClassInstanceCreation ctorClass)
{
Type type = ctorClass.getType();
// Only examine simple types
if (type.isSimpleType())
{
SimpleType simpleType = (SimpleType)type;
String typeName = simpleType.getName().getFullyQualifiedName();
// Check type has correct name
if ("Trace".equals(typeName))
{
List<?> arguments = ctorClass.arguments();
// Only check a single argument
if ((arguments != null) &&
(arguments.size() == 1))
{
Object arg = arguments.get(0);
// Only check a string literal argument
if (arg instanceof StringLiteral)
{
StringLiteral literal = (StringLiteral) arg;
String currentArg = literal.getLiteralValue();
// Check whether argument value is valid
if (!methodName.equals(currentArg))
{
workingops.add(new TraceFnFixOperation(literal.getStartPosition(),
literal.getLength(),
methodName));
}
}
}
}
}
return false;
}
}
The body of TraceChange:
public static class TraceChange extends CompilationUnitChange
{
public TraceChange(String name,
ICompilationUnit cunit,
List<TraceFnFixOperation> ops)
{
super(name, cunit);
MultiTextEdit multiTextEdit= new MultiTextEdit();
setEdit(multiTextEdit);
for (TraceFnFixOperation op : ops)
{
addEdit(new ReplaceEdit(op.startPosition,
op.length,
"\"" + op.methodName + "\""));
}
}
}
-----
I have also posted this question on StackOverflow with the same title (I can't post a link as I am new to this forum).