Roslyn:如何获取与标识符关联的 ITypeSymbol?

Roslyn: How to get the ITypeSymbol associated with an identifier?

我正在尝试编写一个 Roslyn 分析器来检测在数组上调用 Enumerable.Count() 的用法。这是我的分析器中的相关代码:

public override void Initialize(AnalysisContext context)
{
    context.RegisterSyntaxNodeAction(AnalyzeInvocationExpression, SyntaxKind.InvocationExpression);
}

private static void AnalyzeInvocationExpression(SyntaxNodeAnalysisContext context)
{
    var invocation = (InvocationExpressionSyntax)context.Node;
    var memberAccess = invocation.Expression as MemberAccessExpressionSyntax;
    if (!memberAccess.IsKind(SyntaxKind.SimpleMemberAccessExpression))
    {
        return;
    }

    Debug.Assert(memberAccess != null);
    var ident = memberAccess.Name.Identifier;
    // Check whether the method is Count() and there is no parameter list before we try to use the Symbol APIs.
    if (ident.ToString() != nameof(Enumerable.Count))
    {
        return;
    }

    var arguments = invocation.ArgumentList.Arguments;
    if (arguments.Count > 0)
    {
        return;
    }

    // Make sure that the subject is an array.
    var subject = memberAccess.Expression;
    var subjectSymbol = context.SemanticModel.GetSymbolInfo(subject).Symbol;
    if (subjectSymbol == null)
    {
        return;
    }

    // ???
}

我无法确定调用 Count() 的对象是否是一个数组。我扫描了一下 API,我看到有一个 ILocalSymbolType 属性,还有一个 IFieldSymbolType 属性 这可能都会让你得到对象的类型。但是,我不知道我正在分析的对象是否是方法 call/etc 的 local/field/result,所以我希望 IFieldSymbolILocalSymbol 例如共享一些通用的基本接口,比如 IVariableSymbol,它为您提供 Type,而无需知道变量可能来自的所有可能位置。但是,这两个接口似乎都直接派生自 ISymbol.

做这样的事情是最好的解决方案吗?

internal static class SymbolUtilities
{
    public static ITypeSymbol GetType(ISymbol symbol)
    {
        if (symbol is IFieldSymbol)
        {
            return ((IFieldSymbol)symbol).Type;
        }

        if (symbol is ILocalSymbol)
        {
            return ((ILocalSymbol)symbol).Type;
        }

        ...
    }
}

您可以使用 SemanticModel class 的方法 GetTypeInfo 获取有关类型的信息:

ITypeSymbol subjectType = context.SemanticModel.GetTypeInfo(subject).Type;

您将在文章中找到更多详细信息

"Introduction to Roslyn and its use in program development"