2

I am attempting to write a Visual Studio extension that will analyze the C# code displayed in the editor and possibly update the code based on what I find. This would be on demand (via a menu item), and not using an analyzer and code fix.

There are a number of examples and samples on the Internet, but they all start either with the source code hard-coded in the samples, or create a new document, or look at each file in the VS solution that is open. How do I access the source code from the active editor window?

  • Do you actually need the source code or the Document representation from roslyn? The second one can easily be obtained using the VisualStudioWorkspace as described here: https://stackoverflow.com/a/33781511 - the example actually even accesses the currently opened document. – SJP Aug 12 '17 at 19:48
  • @JimOrcheson, Analyzer are just a vistor pattern, which checks the active code in the first place, you setup your Analyzer to check certain types of code like MethodDeclarationSyntax, and then it analyzer those in which you selected, if you are trying to get the neighboring code from that you grab out the document it exists in... – johnny 5 Aug 14 '17 at 20:29
  • Thanks for the link @SJP. After a few days in assembly hell, I finally got the code to execute. And in answer to your question, yes, I think I really want the Document representation from Roslyn. – Jim Orcheson Aug 16 '17 at 01:31
  • @johnny 5. Yes the visitor pattern will be very useful. Since I trigger the analysis from a custom command, I have to retrieve the code and parse it into a SyntaxTree before I can walk it. – Jim Orcheson Aug 16 '17 at 20:34

2 Answers2

1

First, you need to install the Microsoft.CodeAnalysis.EditorFeatures.Text package.

Then you need to add the appropriate using statement:

 using Microsoft.CodeAnalysis.Text;

Now you can map between Visual Studio concepts (ITextSnapshot, ITextBuffer etc.) and Roslyn concepts (Document, SourceText etc.) with the extension methods found here: https://github.com/dotnet/roslyn/blob/master/src/EditorFeatures/Text/Extensions.cs

For example:

ITextSnapshot snapshot = ... //Get this from Visual Studio
var documents = snapshot.GetRelatedDocuments(); //There may be more than one
Softlion
  • 12,281
  • 11
  • 58
  • 88
JoshVarty
  • 9,066
  • 4
  • 52
  • 80
1

In a comment to my original question, @SJP gave a link to @Frank Bakker's answer to the question at Calling Roslyn from VSIX Command. This does work as outlined.

@JoshVarty provided a hint of the direction to go in his answer above. I combined that with code provided by @user1912383 for how to get an IWpfTextView answering the question Find an IVsTextView or IWpfTextView for a given ProjectItem, in 2010 RC extension. Here is the code I came up with:

var componentModel = (IComponentModel)Package.GetGlobalService(typeof(SComponentModel));
var textManager = (IVsTextManager)Package.GetGlobalService(typeof(SVsTextManager));
IVsTextView activeView = null;
ErrorHandler.ThrowOnFailure(textManager.GetActiveView(1, null, out activeView));
var editorAdapter = componentModel.GetService<IVsEditorAdaptersFactoryService>();
var textView = editorAdapter.GetWpfTextView(activeView);
var document  = (textView.TextBuffer.ContentType.TypeName.Equals("CSharp"))
            ? textView : null;

In a comment after @user1912383's code mentioned above, @kman mentioned that this does not work for document types such as .sql files. It does, however, work for .cs files which is what I will be using it with.

  • What is `Extensions` ? I'm stuck at last line – Pawcio Aug 01 '19 at 09:05
  • 1
    @Pawcio I have changed the last line to what I currently use. Note that document either contains either an ItextView object of the code or null. For futher information on what I am doing, see [Creating A Documentation Comment Generator For C#: Setting Up The Framework](https://computingonplains.wordpress.com/creating-a-documentation-comment-generator-for-c-setting-up-the-framework/) – Jim Orcheson Aug 12 '19 at 12:33