如何从Roslyn的using指令中获取完全限定的命名空间?

3
当你在VS2015中悬停在“简化”的using指令上时,它会显示完整限定名称。我应该如何通过Roslyn插件获取此信息?是否需要使用DiagnosticAnalyzer或者CodeFixProvider
通过阅读source.roslyn.codeplex.com的内容,包括如何添加using语句以及简化类型名称(包括using语句),但我无法弄清楚如何反向获取完整限定名称。

3
我假设你需要使用语义模型来检索它所指的类型,然后使用 .ToDisplayString() 找出它的完全限定名。 - Jeroen Vannevel
@JeroenVannevel:你应该把它写成一个答案。;-) - Jason Malinowski
@JasonMalinowski 我一直有点分心,但现在我已经加上了一个 ;-) 也许你可以澄清应该使用什么 SymbolDisplayFormat?我没有预料到 SymbolDisplayFormat.FullyQualifiedFormat 会包括 global:: 前缀。 - Jeroen Vannevel
1个回答

6
通过语义模型,您可以检索有关构成代码的语义信息(显然)-- 这使您可以获取有关类型和其他结构的特定信息。
例如:
void Main()
{
    var tree = CSharpSyntaxTree.ParseText(@"
using X = System.Text;
using Y = System;
using System.IO;

namespace ConsoleApplication1
{
}"
);

    var mscorlib = PortableExecutableReference.CreateFromFile(typeof(object).Assembly.Location);
    var compilation = CSharpCompilation.Create("MyCompilation", syntaxTrees: new[] { tree }, references: new[] { mscorlib });
    var semanticModel = compilation.GetSemanticModel(tree);
    var root = tree.GetRoot();

    // Get usings
    foreach (var usingDirective in root.DescendantNodes().OfType<UsingDirectiveSyntax>())
    {
        var symbol = semanticModel.GetSymbolInfo(usingDirective.Name).Symbol;
        var name = symbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
        name.Dump();
    }
}

输出:

全局::System.Text
全局::System
全局::System.IO

如果您使用 SymbolDisplayFormat.CSharpErrorMessageFormat,您将收到以下内容

System.Text
System
System.IO

您可以选择感兴趣的内容,但正如您所看到的,它可以很好地处理别名并且没有问题。


我应该包括我的示例代码;到达“root.DescendantNodes().OfType<UsingDirectiveSyntax>()”点,然后就不知道如何处理节点。我尝试了“.Name”和将其转换为“QualifiedNameSyntax”,然后完全迷失了方向。 - Jedidja
我正在处理的示例“DiagnosticAnalyzer”没有包含语义模型,因此我开始研究“CodeFixProvider”。 - Jedidja
2
我建议您阅读Josh Varty的这些概念的精彩解析——它们将澄清每个概念的确切含义。https://joshvarty.wordpress.com/learn-roslyn-now/ - Jeroen Vannevel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接