2

I've got a custom plugin which uses a quickfix and the IDocument.InsertText() method. it inserts a comment at the end of the line of code with the highlighter that was selected but this messes up the position of the rest of the highlighters from the one selected to the end. Is there some way to refresh my daemons Execute function which is in charge of placing the highlights?
Any other ideas on ways to get around this?

Thank you, Yuval

Before fix: Before

After fix: After

Mr Boss
  • 472
  • 4
  • 13

1 Answers1

1

This is due to the abstract syntax tree getting out of sync with the text of the document. Normally, you'd modify the source file by manipulating the syntax tree, which in turn updates the text of the document. When modifying the text directly, you need to make sure the syntax tree is notified of the change, so it knows to update.

You can do this by wrapping the update in a transaction:

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

You get to specify the default action that will happen when the transaction cookie's Dispose method is called - commit or rollback, and you can call methods directly on the transaction cookie, too. The text passed to the cookie is plain text and is only used for diagnostics purposes, so you can see the transaction that is currently active.

UPDATE:

After looking at the code, the issue here is that you can't modify the text of the document while there's a PSI transaction active. The PSI transaction indicates that you're going to modify the abstract syntax tree of the document, so you can't then modify the text of the document as well - you could easily get into a situation with two conflicting changes and no way to reconcile them.

The PSI transaction is being created by the BulbActionBase base class of the context action, before calling the ExecutePsiTransaction method. You can't modify the text directly in this method.

You have a couple of choices here. You could create a comment node using CSharpElementFactory.GetInstance(...).CreateComment(text) and then add it to the PSI tree using the methods in ModificationUtil, or you can leave ExecutePsiTransaction as an empty method (return null) and implement ExecuteAfterPsiTransaction and call Document.InsertText there (this is what the XAML InsertTextQuickFix class does). Because this method is called while in a transaction, but not while in a PSI transaction, it should update the text, and cause the PSI to be put back in sync.

Incidentally, ReSharper throws an exception when trying to modify the document while the PSI transaction is active, with an appropriate message. If you run Visual Studio with the command line devenv.exe /ReSharper.Internal, this exception should be shown as a tooltip like window in the status bar. Even better, if you're building a plugin, you can install a "checked" build, which includes more checks and reports exceptions by default.

citizenmatt
  • 18,085
  • 5
  • 55
  • 60
  • Hey citizenmatt, thanks for the response. Tried toying with this and nothing is working. Am I doing something wrong here? Thanks again! using(solution.CreateTransactionCookie(DefaultAction.Commit, "L10N insterted")) { _highlighter.Declaration.GetSourceFile().Document.InsertText(location, commentString); } – Mr Boss Apr 10 '14 at 19:30
  • Yes, that should be it. What happens when you do it? Does the highlight just not move? Try running `devenv.exe /ReSharper.Internal`, which enables exception reporting, to see if ReSharper is complaining about it. And if you're developing plugins, using the checked build is also strongly recommended - all internal asserts are compiled into this build, which can be very helpful: http://resharper-support.jetbrains.com/entries/21206508-Where-can-I-download-an-old-previous-ReSharper-version- – citizenmatt Apr 11 '14 at 08:19
  • The highlight moves down in position the same amount of the comment added to the line which was fixed. If I type a letter or close/open file again it fixes it but does not refresh the other highlights when I alt-enter and fix a highlight. Does that make sense? I'm working on fixing this now using checked build I'll let you know if I figure anything out, thanks! Also added images to question might help understand more. – Mr Boss Apr 11 '14 at 20:43
  • OK, looking at the images, the highlights don't move, but the text does, so the highlights are now in the wrong position. This happens if you don't create a transaction. If you do create a transaction, do you see exactly the same thing? – citizenmatt Apr 14 '14 at 10:19
  • Yes, same issue when using CreateTransactionCookie as without it. Only thing I can think of at the moment is updating the docRange of all the highlights but it would be nice if I could trigger some sort of file refresh. Thanks again for all the help! – Mr Boss Apr 14 '14 at 16:31
  • It should trigger the update itself. Do you have a repro I can take a look at? You can email it to me matt.ellis @ jetbrains.com if you want to keep it private. – citizenmatt Apr 15 '14 at 09:55