使用 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
.
我在大型 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
.