从Visual Studio文本选择中获取Roslyn SyntaxToken(插入位置)

我试图在Visual Studio扩展包中的VSSDK和Roslyn SDK之间架起桥梁,并且一直很难用。 Visual Studio提供的ActivePoint.AbsoluteCharOffset与使用FindToken(offset)时从Roslyn获取的元素不匹配。 我很确定这与我的当前工作黑客的每一方如何计算EOL字符有关,但我不是100%,我的黑客将长期坚持。

我的黑客是这一行: charOffset += point.Line;

我在char偏移量上添加了行数,这似乎有效,所以我猜我正在添加所有被activepoint计数忽略的换行符。

助手

 private VisualStudioWorkspace workspace = null; public RoslynUtilities(VisualStudioWorkspace workspace) { this.workspace = workspace; } public Solution Solution { get { return workspace.CurrentSolution; } } public Document GetDocumentFromPath(string fullPath) { foreach (Project proj in this.Solution.Projects) { foreach (Document doc in proj.Documents) { if (doc.FilePath == fullPath) return doc; } } return null; } public SyntaxTree GetSyntaxTreeFromDocumentPath(string fullPath) { Document doc = GetDocumentFromPath(fullPath); if (doc != null) return doc.GetSyntaxTreeAsync().Result; else return null; } public SyntaxNode GetNodeByFilePosition(string fullPath, int absoluteChar) { SyntaxTree tree = GetSyntaxTreeFromDocumentPath(fullPath); if(tree != null) { var compUnit = tree.GetCompilationUnitRoot(); if(compUnit != null) { return compUnit.FindToken(absoluteChar, true).Parent; } } return null; } private VisualStudioWorkspace GetRoslynWorkspace() { var componentModel = (IComponentModel)GetGlobalService(typeof(SComponentModel)); return componentModel.GetService(); } 

主要部分

 EnvDTE80.DTE2 applicationObject = (EnvDTE80.DTE2)GetService(typeof(SDTE)); EnvDTE.TextSelection ts = applicationObject.ActiveWindow.Selection as EnvDTE.TextSelection; if (ts == null) return; EnvDTE.VirtualPoint point = ts.ActivePoint; int charOffset = point.AbsoluteCharOffset; charOffset += point.Line;//HACK ALERT Parse.Roslyn.RoslynUtilities roslyn = new Parse.Roslyn.RoslynUtilities(GetRoslynWorkspace()); SyntaxNode node = roslyn.GetNodeByFilePosition(applicationObject.ActiveDocument.FullName, charOffset); 

我强烈建议使用Microsoft.VisualStudio.Text.SnapshotPoint缓冲区中的Microsoft.VisualStudio.Text.Editor.IWpfTextView而不是EnvDTE接口与Roslyn进行交互。

主要代码可能如下所示:

 Microsoft.VisualStudio.Text.Editor.IWpfTextView textView = GetTextView(); Microsoft.VisualStudio.Text.SnapshotPoint caretPosition = textView.Caret.Position.BufferPosition; Microsoft.CodeAnalysis.Document document = caretPosition.Snapshot.GetOpenDocumentInCurrentContextWithChanges(); Microsoft.CodeAnalysis.CSharp.Syntax.InvocationExpressionSyntax invocationExpressionNode = document.GetSyntaxRootAsync().Result. FindToken(caretPosition).Parent.AncestorsAndSelf(). OfType(). FirstOrDefault(); 

有关完整示例,请参阅从当前方法调用创建类型变量 。