How to use rename refactoring as part of a quickfix?

淺唱寂寞╮ 提交于 2019-12-08 02:20:46

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!