Roslyn:如何让ITypeSymbol与标识符相关联?

时间:2017-02-26 01:24:33

标签: c# .net roslyn

我正在尝试编写一个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,我发现ILocalSymbol有一个Type属性,还有一个IFieldSymbol属性Type,这两个属性都可能会让你获得类型对象。但是,我不知道我正在分析的对象是方法调用/ etc的本地/字段/结果,所以我希望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;
        }

        ...
    }
}

1 个答案:

答案 0 :(得分:2)

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

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

您可以在文章

中找到有关它的更多详细信息

" Introduction to Roslyn and its use in program development"