diff --git a/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/DateTimeConversionTests.cs b/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/DateTimeConversionTests.cs index 4d9d785f..dfd6a315 100644 --- a/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/DateTimeConversionTests.cs +++ b/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/DateTimeConversionTests.cs @@ -200,7 +200,7 @@ static void Main(string[] args) Id = "INTL0202", Severity = DiagnosticSeverity.Warning, Message = "Using the symbol 'DateTimeOffset.implicit operator DateTimeOffset(DateTime)' can result in unpredictable behavior", - Locations = [new DiagnosticResultLocation("Test0.cs", 15, 36)] + Locations = [new DiagnosticResultLocation("Test0.cs", 14, 36)] } ); } diff --git a/IntelliTect.Analyzer/IntelliTect.Analyzer/Analyzers/BanImplicitDateTimeToDateTimeOffsetConversion.cs b/IntelliTect.Analyzer/IntelliTect.Analyzer/Analyzers/BanImplicitDateTimeToDateTimeOffsetConversion.cs index 46940659..af738d22 100644 --- a/IntelliTect.Analyzer/IntelliTect.Analyzer/Analyzers/BanImplicitDateTimeToDateTimeOffsetConversion.cs +++ b/IntelliTect.Analyzer/IntelliTect.Analyzer/Analyzers/BanImplicitDateTimeToDateTimeOffsetConversion.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Immutable; +using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Operations; @@ -33,22 +34,35 @@ public override void Initialize(AnalysisContext context) private void AnalyzeInvocation(OperationAnalysisContext context) { - if (context.Operation is not IConversionOperation conversionOperation) + if (context.Operation is not IConversionOperation conversionOperation || !conversionOperation.Conversion.IsImplicit) { return; } - if (conversionOperation.Conversion.IsImplicit && conversionOperation.Conversion.MethodSymbol is object && conversionOperation.Conversion.MethodSymbol.ContainingType is object) + if (conversionOperation.Conversion.MethodSymbol is object && conversionOperation.Conversion.MethodSymbol.ContainingType is object) { INamedTypeSymbol containingType = conversionOperation.Conversion.MethodSymbol.ContainingType; - INamedTypeSymbol dateTimeOffsetType = context.Compilation.GetTypeByMetadataName("System.DateTimeOffset"); - if (SymbolEqualityComparer.Default.Equals(containingType, dateTimeOffsetType)) + if (IsDateTimeOffsetSymbol(context, containingType)) { context.ReportDiagnostic(Diagnostic.Create(_Rule202, conversionOperation.Syntax.GetLocation())); } } + else + { + bool hasImplicitArg = conversionOperation.Operand.ChildOperations + .Where(op => op.Kind == OperationKind.Argument && IsDateTimeOffsetSymbol(context, ((IArgumentOperation)op).Value.Type)) + .Any(); + if (hasImplicitArg) + { + context.ReportDiagnostic(Diagnostic.Create(_Rule202, conversionOperation.Syntax.GetLocation())); + } + } + } - + private static bool IsDateTimeOffsetSymbol(OperationAnalysisContext context, ITypeSymbol symbol) + { + INamedTypeSymbol dateTimeOffsetType = context.Compilation.GetTypeByMetadataName("System.DateTimeOffset"); + return SymbolEqualityComparer.Default.Equals(symbol, dateTimeOffsetType); } private static class Rule202