Jon Skeet
Jon Skeet

Reputation: 1500873

How can I make my code diagnostic syntax node action work on closed files?

I'm building a set of code diagnostics using Roslyn (in VS2015 Preview). Ideally, I'd like any errors they produce to act as persistent errors, just as if I were violating a normal language rule.

There are a bunch of options, but I'm having a hard time getting any of them to work consistently. I've managed to implement a rudimentary syntax node action, i.e. one registered with

context.RegisterSyntaxNodeAction(AnalyzeSyntaxNode, SyntaxKind.InvocationExpression);

in the Initialize method of my diagnostic class. Lo and behold, when I open up a file which violates this diagnostic (while running the VSIX project), VS2015 shows an error:

However, the error goes away when I close the file.

I've tried using context.RegisterCompilationEndAction as well, but this has two problems:

What am I doing wrong here? The first approach (a syntax node action) would be ideal if feasible - it gives me exactly the context I need. Is there some setting in the project properties that I need to make the compiler use that for "full project" compilation as well as just interactive "in the IDE" handling? Is this perhaps just a bit of Roslyn integration which isn't quite finished yet?

(I can include the full code for the class if it would be useful - in this case I suspect it would be more noise than signal though.)

Upvotes: 73

Views: 4570

Answers (1)

Kevin Pilch
Kevin Pilch

Reputation: 11615

For the closed file issues, it's our intent that all diagnostics will be reported, from either open or closed files. There is a user option for it in the preview at Tools\Options\Text Editor\C#\Advanced that you can toggle to include diagnostics in closed files. We hope to make this the default before VS 2015 is released. However, note that the option only applies to analysis within VS. If your analyzer is passed to the compiler (by adding an analyzer in Solution Explorer, or adding a NuGet package reference to a package with an analyzer, as opposed to installing a VSIX into Visual Studio), then the compiler will report all diagnostics when the user builds, regardless of whether the files are open or not.

For the second issue with RegisterCompilationEndedAnalyzer, it isn't reliably called inside Visual Studio in the VS 2015 Preview. This is because we do some optimizations to avoid re-analyzing everything for "local" changes inside method bodies. For similar reasons, we currently don't report errors that are reported with locations in method bodies. We've just recently changed that so that VS will kick off a full re-analysis after a longer delay and so RegisterCompilationEndedAnalyzer should be called reliably in future builds, and we will report errors regardless of location.

However, for your case the correct thing to do is stay with a SyntaxNodeAnalyzer, switch the VS option to enable diagnostics in closed files, and attach your diagnostic to the project compilation options.

Hope this helps!

Upvotes: 46

Related Questions