问题
I've added a quickfix option to my DSL in which I want to make some modifications to the document text - including renaming some element. I can change text in that element just fine, but I want to also rename all of its references - i.e. rename refactoring. How do I do that?
Can I somehow trigger the built-in rename refactoring from inside a quickfix? Or alternatively, how do I go over all of the element's references and change them?
回答1:
So, I found a way to programmatically trigger a rename refactor. I don't know if it's the "proper" way - I guess it isn't, since I had to add @SuppressWarnings("restriction")
to my code - but it works:
private void performDirectRenameRefactoring(EObject object, String newName) throws InterruptedException {
XtextEditor editor = EditorUtils.getActiveXtextEditor();
IRenameElementContext renameContext = new IRenameElementContext.Impl(
EcoreUtil.getURI(object),
object.eClass(),
editor,
editor.getSelectionProvider().getSelection(),
null);
IRenameSupport rename = renameSupportFactory.create(renameContext, newName);
rename.startDirectRefactoring();
}
So to call this from a quick fix, all you need to do is to get the EObject
and calculate the new name. If the issue occupies a part of the EObject
itself, the object could be retrieved by:
private EObject findObject(IXtextDocument doc, final Issue issue) {
EObject object = doc.readOnly(new IUnitOfWork<EObject, XtextResource>() {
public EObject exec(XtextResource state) throws Exception {
return state.getEObject(issue.getUriToProblem().fragment());
}
});
}
You can get an IXtextDocument
from either IssueResolutionAcceptor
(which you should have if you're handling an issue) or from IModificationContext
(which you should have if you're proposing a change).
回答2:
Oak, thank you very much for the solution. Here is my version in Xtend.
@Inject(optional=true)
IRenameSupport.Factory renameSupportFactory;
@Inject(optional=true)
IRenameContextFactory renameContextFactory;
@Fix(VhdlValidator::INVALID_SIGNAL_NAME_ENDING)
def addSignalEnding(Issue issue, IssueResolutionAcceptor acceptor) {
acceptor.accept(issue, 'Add the "_s" ending', 'Add the "_s" ending.', 'upcase.png') [
EObject element, IModificationContext context |
val editor = EditorUtils.getActiveXtextEditor();
val renameElementContext = editor.getDocument().readOnly(
new IUnitOfWork<IRenameElementContext, XtextResource>()
{
override def IRenameElementContext exec(XtextResource state)
{
renameContextFactory.createRenameElementContext(element,
editor, null, state);
}
});
val rename = renameSupportFactory.create(renameElementContext, (element as Signal).name + "_s" );
rename.startDirectRefactoring();
]
}
来源:https://stackoverflow.com/questions/14480917/how-to-use-rename-refactoring-as-part-of-a-quickfix