简体   繁体   中英

How do I retrieve text from the Visual Studio editor for use with Roslyn SyntaxTree?

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?

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM