【问题标题】:How to get all C# types or namespaces that Roslyn couldn't find?如何获取 Roslyn 找不到的所有 C# 类型或命名空间?
【发布时间】:2020-07-06 20:23:54
【问题描述】:

我正在使用 Roslyn 解析 C# 项目。我有一个代表这个项目的Microsoft.CodeAnalysis.Compilation 对象。但是,这个项目可能没有编译成功;这可能有几个原因,但我对任何对无法解析的类型或命名空间的引用特别感兴趣。 如何使用我的Compilation 对象将所有未知命名空间或类型检索为IErrorTypeSymbols?

【问题讨论】:

    标签: c# roslyn code-analysis roslyn-code-analysis


    【解决方案1】:

    最简单的方法是遍历所有SyntaxTrees 并使用编译的SemanticModel 来识别错误类型。

    类似...

    // assumes `comp` is a Compilation
    
    // visit all syntax trees in the compilation
    foreach(var tree in comp.SyntaxTrees)
    {
        // get the semantic model for this tree
        var model = comp.GetSemanticModel(tree);
        
        // find everywhere in the AST that refers to a type
        var root = tree.GetRoot();
        var allTypeNames = root.DescendantNodesAndSelf().OfType<TypeSyntax>();
        
        foreach(var typeName in allTypeNames)
        {
            // what does roslyn think the type _name_ actually refers to?
            var effectiveType = model.GetTypeInfo(typeName);
            if(effectiveType.Type != null && effectiveType.Type.TypeKind == TypeKind.Error)
            {
                // if it's an error type (ie. couldn't be resolved), cast and proceed
                var errorType = (IErrorTypeSymbol)effectiveType.Type;
    
                // do what you want here
            }
        }
    }
    

    在抓取后,未知名称空间需要更多技巧,因为您无法真正判断 Foo.Bar 是指“Foo 中的类型 Bar”还是没有元数据的“名称空间 Foo.Bar”。可能我忘记了 Roslyn 会偷运类型引用语法节点的某个地方……但我记得TypeName

    【讨论】:

    • 成功了,谢谢!这将检索未知类型和未知名称空间;在我的用例中,只要我能获得关于两者的信息,我就不需要区分。我正在为人类而不是其他程序输出诊断信息。
    【解决方案2】:

    您可以使用返回 SymbolInfo 的语义模型.GetSymbolInfo(identifierNameSyntax)。 SymbolInfo.Symbol 是一个 ISymbol,因此您可以使用 ISymbol.ContainingNamespace 来获取标识符所属的命名空间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-25
      • 2015-06-11
      • 2011-06-28
      • 1970-01-01
      • 2019-07-17
      • 2021-08-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多