给定一个SyntaxNode
实例,我如何打开适当的源代码文件并将光标放在节点所在的位置?
我正在写一些简单的分析器。我可以按需启动它并从当前光标位置获取语法节点。但我不知道如何从结果语法节点返回编辑器。我看到节点有一个Span
属性,但除此之外我没有看到任何信息。我要显示的节点可以在其他一些甚至可能无法打开的文件中。
我希望我的搜索结果具有类似于“转到...”命令的行为。
给定一个SyntaxNode
实例,我如何打开适当的源代码文件并将光标放在节点所在的位置?
我正在写一些简单的分析器。我可以按需启动它并从当前光标位置获取语法节点。但我不知道如何从结果语法节点返回编辑器。我看到节点有一个Span
属性,但除此之外我没有看到任何信息。我要显示的节点可以在其他一些甚至可能无法打开的文件中。
我希望我的搜索结果具有类似于“转到...”命令的行为。
我花了一整天的时间,但终于明白了。
private void selectNodeInEditor(SyntaxNode n) {
var cm = (IComponentModel)Package.GetGlobalService(typeof(SComponentModel));
var tm = (IVsTextManager)Package.GetGlobalService(typeof(SVsTextManager));
var ws = (Workspace)cm.GetService<VisualStudioWorkspace>();
var did = ws.CurrentSolution.GetDocumentId(n.SyntaxTree);
ws.OpenDocument(did);
tm.GetActiveView(1, null, out var av);
var sp = n.GetLocation().GetMappedLineSpan().StartLinePosition;
var ep = n.GetLocation().GetMappedLineSpan().EndLinePosition;
av.SetSelection(sp.Line, sp.Character, ep.Line, ep.Character);
}
语法节点有一个GetLocation()
方法,它Microsoft.CodeAnalysis.Location
为该语法节点返回一个,所以这是从SyntaxNode
.
var nodeLocation = syntaxNode.GetLocation();
如果您碰巧也需要符号,还可以使用界面Locations
上的属性从符号中获取位置信息。ISymbol
从文档:
获取最初在源或元数据中定义符号的位置。某些符号(例如,部分类)可能在多个位置定义。
https://docs.microsoft.com/en-us/dotnet/api/microsoft.codeanalysis.isymbol?view=roslyn-dotnet
这可能是可取的,因为根据 的类型SyntaxNode
,您可能想要获取符号的原始定义而不是符号本身,例如,您可以从字段的类型中获取类声明。这可以通过OriginalDefinition
属性来完成。
// assumes there's a SemanticModel in scope and your node is called synatxNode
var syntaxNodeSymbol = semanticModel.GetSymbolInfo(syntaxNode).Symbol;
// make sure syntaxNodeSymbol is null checked
var nodeLocation = syntaxNodeSymbol.Locations[0];
var originalNodeLocation = syntaxNodeSymbol.OriginalDefinition.Locations[0];
至于实际跳转到节点,这个问题可能是一个很好的起点: Go to definition from text position with roslyn
但是,通过双击错误列表面板中的消息,这已经可以在 Visual Studio 中实现。此外,您想在该位置进行的任何代码修复都将显示在代码修复窗口中。