2017-02-26 32 views
1

我正在嘗試編寫一個Roslyn分析器來檢測在陣列上調用的Enumerable.Count()的用法。這裏是我分析的相關代碼:Roslyn:如何獲取與標識符關聯的ITypeSymbol?

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屬性,這兩個屬性都可能讓你知道對象的類型。但是,我不知道我要分析的對象是方法調用/本地/字段/結果,因此我期望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; 
     } 

     ... 
    } 
} 

回答

相關問題