c# - 在 C# 编辑器窗口中查找当前位置的项目类型

标签 c# visual-studio vs-extensibility roslyn

我正在编写 Visual Studio 智能感知的扩展,并希望在 C# 编辑器中获取光标之前的项目类型。

我目前有一个 ITextBuffer,我可以用它来获取当前的源文件。

我还可以获得编辑器中的当前位置,如下所示:

var dte = Microsoft.VisualStudio.Shell.ServiceProvider.GlobalProvider.GetService(typeof(EnvDTE._DTE)) as EnvDTE.DTE;            
TextSelection sel = (TextSelection)dte.ActiveDocument.Selection;

但是我不太确定如何检测当前在编辑器中光标后面的项目的类型。我试过使用 Roslyn,但看起来这应该比这简单得多。 Roslyn 是执行此操作的最佳工具(通过编译文档并导航到文档中的正确位置)还是有更好的方法。

下面是我尝试使用 Roslyn 查找项目类型的尝试:

ITextSnapshot snapshot = m_textBuffer.CurrentSnapshot;
SnapshotPoint? triggerPoint = session.GetTriggerPoint(snapshot);

var tree = SyntaxTree.ParseCompilationUnit(m_textBuffer.CurrentSnapshot.GetText());

var nodes = tree.GetRoot().DescendantNodes();

var element = nodes.Where(n => n.Span.End <= triggerPoint.Value.Position).Last();

var comp = Compilation.Create("test", syntaxTrees: new[] { tree });
var semModel = comp.GetSemanticModel(tree);

//I cant work out what to do here to get the type as the element doesnt seem to be of the required type
var s = semModel.GetTypeInfo((AttributeSyntax)element);

最佳答案

编译器 API 非常慎重,要求您提出正确的问题(没有模糊逻辑。)简单地查找光标位置处的事物类型需要一些上下文,而一开始对您来说似乎显而易见的答案可能不是其他用途的正确答案。

对于一般表达式,您可以这样做:(注意它不是很健壮)

var root = tree.GetRoot();
var token = root.FindToken(pos);
var nearestExpr = token.Parent.AncestorsAndSelf().OfType<ExpressionSyntax>().First();
var type = semModel.GetTypeInfo(nearestExpr).Type;

一个更全面的解决方案是检查 token 的父节点并从那里开始:

var node = token.Parent;
if (node is ExpressionSyntax)
{
    type = semModel.GetTypeInfo((ExpressionSyntax)node).Type;
}
else if (node is VariableDeclaratorSyntax && ((VariableDeclaratorSyntax)node).Identifier == token)
{
    type = (TypeSymbol)semModel.GetDeclaredSymbol((VariableDeclaratorSyntax)node);   
}

...

有很多有趣的案例,您想要显示为对应于源文件中任何特定标识符或标记的类型的内容可能会有所不同,具体取决于您要完成的任务。

关于c# - 在 C# 编辑器窗口中查找当前位置的项目类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11308106/

相关文章:

javascript - 将数组从客户端传递到服务端 C#

C#,动态创建图片框?

c# - AsyncPostBackTrigger 不是已知元素?

c# - 在 Visual Studio 源 View 中显示图像或控件

visual-studio-2015 - 在 Visual Studio 扩展中使用内置图标

c# - 异步使用 System.Diagnostics.Process,我应该如何确保在确定它已退出之前收到最后的输出?

c# - 使用正则表达式替换

eclipse - 为Visual Studio、VS code和Eclipse设置常用快捷键

c++ - 在 Visual Studio 中从原始 C++ 代码创建项目时保留原始文件夹结构

c# - Visual Studio Extensibility Package 没有查看正确的项目