2

我有一个使用 quickfix 和IDocument.InsertText()方法的自定义插件。它在代码行的末尾插入了一条注释,带有选中的荧光笔,但这会混淆其余荧光笔的位置,从所选的荧光笔到最后。有什么方法可以刷新我的负责放置亮点的守护进程执行功能吗?
关于如何解决这个问题的任何其他想法?

谢谢你,尤瓦尔

修复前: 前

修复后: 后

4

1 回答 1

1

这是因为抽象语法树与文档文本不同步。通常,您会通过操作语法树来修改源文件,而语法树又会更新文档的文本。当直接修改文本时,您需要确保语法树被通知更改,因此它知道要更新。

您可以通过将更新包装在事务中来做到这一点:

using(solution.CreateTransactionCookie(DefaultAction.Commit, "Update text"))
{
  document.InsertText(...);
}

您可以指定调用事务 cookie 的方法时将发生的默认操作Dispose- 提交或回滚,您也可以直接在事务 cookie 上调用方法。传递给 cookie 的文本是纯文本,仅用于诊断目的,因此您可以看到当前处于活动状态的事务。

更新:

查看代码后,这里的问题是您无法在 PSI 事务处于活动状态时修改文档的文本。PSI 事务表明您将要修改文档的抽象语法树,因此您也不能修改文档的文本 - 您很容易陷入两个更改冲突且无法协调的情况他们。

PSI 事务由BulbActionBase上下文操作的基类在调用ExecutePsiTransaction方法之前创建。您不能在此方法中直接修改文本。

你在这里有几个选择。您可以使用创建注释节点CSharpElementFactory.GetInstance(...).CreateComment(text),然后使用 中的方法将其添加到 PSI 树中ModificationUtil,或者您可以保留ExecutePsiTransaction为空方法 (return null) 并在那里实现ExecuteAfterPsiTransaction和调用Document.InsertText(这是 XAMLInsertTextQuickFix类所做的)。因为在事务中调用此方法,而不是在 PSI 事务中调用,所以它应该更新文本,并使 PSI 重新同步。

顺便说一句,当 PSI 事务处于活动状态时尝试修改文档时,ReSharper 会引发异常,并带有适当的消息。如果您使用命令行运行 Visual Studio,则devenv.exe /ReSharper.Internal此异常应在状态栏中显示为类似窗口的工具提示。更好的是,如果你正在构建一个插件,你可以安装一个 "checked" build,默认情况下它包括更多的检查和报告异常。

于 2014-04-10T08:11:01.570 回答