从VSIX命令调用Roslyn

问题描述 投票:6回答:3

从EnvDTE.ProjectItem获取Roslyn的SyntaxTree的最佳方法是什么?我找到了另一种方法(Roslyn的Document into ProjectItem)。

我从打开的文档中调用了VSIX命令,我想在那里试验Roslyn的语法树。

这段代码有效,但对我来说看起来很尴尬:

    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))

有没有更好的方法从活动文档中获取Roslyn的文档?

visual-studio-2015 roslyn vsix vsx visual-studio-package
3个回答
8
投票

您可以使用workspace.CurrentSolution.GetDocumentIdsWithFilePath()来获取与文件路径匹配的DocumentId。从那里你可以使用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);
}

6
投票

弗兰克的回答很有效。我发现很难弄清楚类型名称是什么,所以这里是Frank的完全限定类型名称的代码:

using System.Linq;

var dte = Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(EnvDTE.DTE)) as EnvDTE.DTE;
var activeDocument = dte?.ActiveDocument;
if (activeDocument != null)
{
    var componentModel = (Microsoft.VisualStudio.ComponentModelHost.IComponentModel)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(Microsoft.VisualStudio.ComponentModelHost.SComponentModel));
    var workspace = (Microsoft.CodeAnalysis.Workspace)componentModel.GetService<Microsoft.VisualStudio.LanguageServices.VisualStudioWorkspace>();
    var documentId = workspace.CurrentSolution.GetDocumentIdsWithFilePath(activeDocument.FullName).FirstOrDefault();
    if (documentId != null)
    {
        var document = workspace.CurrentSolution.GetDocument(documentId);
    }
}

以下是查找这些类型的参考:

我希望这两个框架引用可以替换为对gazxswpoi和VSSDK.DTE的NuGet引用,但是当我尝试时,它给出了关于程序集版本不匹配的构建警告,所以我放弃了。


1
投票

如果你能弄清楚如何从VSSDK.ComponentModelHost到编辑ProjectItem,那么最好使用ITextSnapshot

另请注意,在上面的代码中,通过使用snapshot.AsText().GetOpenDocumentInCurrentContextWithChanges(),您依赖于在您之前请求解析树的其他人。

© www.soinside.com 2019 - 2024. All rights reserved.