Search code examples
visual-studio-2015roslynvsixvsxvisual-studio-package

calling Roslyn from VSIX command


What is best way to obtain Roslyn's SyntaxTree from EnvDTE.ProjectItem? I found some method for the other way (Roslyn's Document into ProjectItem).

I got VSIX command called from opened document and I'd like to experiment with Roslyn's syntax tree there.

This code works, but looks awkward to me:

    var pi = GetProjectItem();
    var piName = pi.get_FileNames(1);

    var componentModel = (IComponentModel)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SComponentModel));
    var workspace = componentModel.GetService<Microsoft.VisualStudio.LanguageServices.VisualStudioWorkspace>();
    var ids = workspace.GetOpenDocumentIds();
    var id1 = ids.First(id => workspace.GetFilePath(id) == piName);

        Microsoft.CodeAnalysis.Solution sln = workspace.CurrentSolution;
        var doc = sln.GetDocument(id1);
        //var w = await doc.GetSyntaxTreeAsync();
        Microsoft.CodeAnalysis.SyntaxTree syntaxTree;
        if (doc.TryGetSyntaxTree(out syntaxTree))

Is there better way to get Roslyn's Document from active document?


Solution

  • You can use workspace.CurrentSolution.GetDocumentIdsWithFilePath() to get the DocumentId(s) matching a file path. From that you can get the document itself using workspace.CurrentSolution.GetDocument()

    private Document GetActiveDocument()
    {
        var dte = Package.GetGlobalService(typeof(DTE)) as DTE;
        var activeDocument = dte?.ActiveDocument;
        if (activeDocument == null) return null;
    
        var componentModel = (IComponentModel)Package.GetGlobalService(typeof(SComponentModel));
        var workspace = (Workspace) componentModel.GetService<VisualStudioWorkspace>();
    
        var documentid = workspace.CurrentSolution.GetDocumentIdsWithFilePath(activeDocument.FullName).FirstOrDefault();
        if (documentid == null) return null;
    
        return workspace.CurrentSolution.GetDocument(documentid);
    }