如何使用重命名重构作为quickfix的一部分?

时间:2013-01-23 13:30:32

标签: xtext

我已经在我的DSL中添加了一个quickfix选项,我想在其中对文档文本进行一些修改 - 包括重命名一些元素。我可以很好地更改该元素中的文本,但我还想重命名它的所有引用 - 即重命名重构。我该怎么做?

我可以以某种方式从quickfix内部触发内置重命名重构吗?或者,我如何查看所有元素的引用并更改它们?

2 个答案:

答案 0 :(得分:1)

所以,我找到了一种以编程方式触发重命名重构的方法。我不知道它是否是“正确的”方式 - 我想它不是,因为我必须将@SuppressWarnings("restriction")添加到我的代码中 - 但它有效:

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();
}

所以要通过快速修复来调用它,您只需要获取EObject并计算新名称。如果问题占据EObject本身的一部分,则可以通过以下方式检索对象:

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());
        }
    });
}

您可以从IXtextDocument(如果您正在处理问题时应该拥有)或IssueResolutionAcceptor获得IModificationContext(如果您提出的话,您应该拥有{{1}}变化)。

答案 1 :(得分:0)

Oak,非常感谢你的解决方案。这是我在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();

    ]
}