使用 Roslyn 分析器查找 DateTime.Now/Today/UtcNow 的所有用法

Find all usages of DateTime.Now/Today/UtcNow with a Roslyn Analyzer

我在大型 C# 应用程序中实现了 TimeProvider,以便集中控制应用程序时间。我想确保将来没有人使用 DateTime.Now/Today/UtcNow,因为这会绕过前面提到的实现。相反,我希望分析器建议使用我的 TimeProviderService,这样就不会在例如代码审查中遗漏它。

我想用分析仪解决这个问题,所以我的问题是:我该怎么做?

以下是我的尝试之一;然而,这似乎引发了 FxCop 的某种遗留问题:

[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class Analyzer : DiagnosticAnalyzer
{

    public override void Initialize(AnalysisContext context)
    {
        context.RegisterSyntaxNodeAction(AnalyzeSymbol, SyntaxKind.IdentifierName);
    }

    public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; }

    public static string DiagnosticId = "1337";

    private static void AnalyzeSymbol(SyntaxNodeAnalysisContext context)
    {
        var token = context.Node.GetFirstToken();
        if (token.ToString().Equals("DateTime"))
        {
            var nextToken = token.GetNextToken();

            if (nextToken.IsKind(SyntaxKind.DotToken))
            {
                var dateTimeProperty = nextToken.GetNextToken();

                var descripter = new DiagnosticDescriptor(DiagnosticId, "DateTime.Today: Use the TimeProvider.Today instead", "", "Noitso best practise", DiagnosticSeverity.Error, isEnabledByDefault: true);

                if (dateTimeProperty.ToString().Equals("Now"))
                {
                    context.ReportDiagnostic(Diagnostic.Create(descripter, context.Node.GetLocation(), "DateTime.Now: Use the TimeProvider.Now instead"));
                }
                else if (dateTimeProperty.ToString().Equals("Today"))
                {

                    context.ReportDiagnostic(Diagnostic.Create(descripter, context.Node.GetLocation()));
                }
                else if (dateTimeProperty.ToString().Equals("UtcNow"))
                {
                    context.ReportDiagnostic(Diagnostic.Create(descripter, context.Node.GetLocation(), "DateTime.UtcNow: Use the TimeProvider.UtcNow instead"));
                }
            }
        }
    }
}

我重新创建了我的项目,解决了遗留问题。我不知道我第一次创建它时做错了什么 :)。

代码 几乎 有效,因为它有一个缺陷 var dateTimeProperty = token.GetNextToken(); 引用了错误的标记,它应该引用 nextToken.