Найти все использования DateTime.Now/Today/UtcNow с анализатором Roslyn - PullRequest
1 голос
/ 21 ноября 2019

Я реализовал TimeProvider в большом приложении C #, чтобы обеспечить централизованный контроль времени приложения. В будущем я хочу убедиться, что никто не использует 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"));
                }
            }
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 22 ноября 2019

Я воссоздал свой проект, который решил устаревшую проблему. Я понятия не имею, что я сделал неправильно, когда я создал это в первый раз :).

Код почти работал, поскольку у него был один недостаток var dateTimeProperty = token.GetNextToken(); ссылается на неправильный токен, он должен ссылаться на nextToken.

0 голосов
/ 21 ноября 2019

Это не прямой ответ, а простая и быстрая альтернатива

  1. Открыть Вид меню Visual Studio> Обозреватель объектов
  2. В типе DateTime
  3. В левой части выберите System.DateTime
  4. В правой части выберите Now / UtcNow
  5. Теперь щелкните правой кнопкой мыши и выберите Найти все ссылки
...