diff --git a/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/Data/DateTime_ImplicitConversion_InLinq.cs b/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/Data/DateTime_ImplicitConversion_InLinq.cs new file mode 100644 index 00000000..933c9008 --- /dev/null +++ b/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/Data/DateTime_ImplicitConversion_InLinq.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace ConsoleApp1 +{ + internal class Pair + { + public DateTimeOffset DateTimeOffset { get; init; } + public DateTime DateTime { get; init; } + + public Pair(DateTimeOffset dateTimeOffset, DateTime dateTime) + { + DateTimeOffset = dateTimeOffset; + DateTime = dateTime; + } + } + + internal class Program + { + static void Main(string[] args) + { + List list = new(){ new(DateTimeOffset.Now, DateTime.Now) }; + _ = list.Where(pair => pair.DateTimeOffset < pair.DateTime); + } + } +} diff --git a/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/DateTimeConversionTests.cs b/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/DateTimeConversionTests.cs index 12ef0640..9fdec794 100644 --- a/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/DateTimeConversionTests.cs +++ b/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/DateTimeConversionTests.cs @@ -1,4 +1,6 @@ -using Microsoft.CodeAnalysis; +using System; +using System.IO; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.VisualStudio.TestTools.UnitTesting; using TestHelper; @@ -40,7 +42,7 @@ static void Main(string[] args) } [TestMethod] - public void UsageOfImplicitConversionInComparison_ProducesWarningMessage() + public void UsageOfImplicitConversionInComparison_DateTimeToDateTimeOffset_ProducesWarningMessage() { string source = @" using System; @@ -53,15 +55,42 @@ internal class Program static void Main(string[] args) { DateTime first = DateTime.Now; + DateTimeOffset second = DateTimeOffset.Now; + _ = first < second + } + } +}"; - Thread.Sleep(10); + VerifyCSharpDiagnostic(source, + new DiagnosticResult + { + Id = "INTL0202", + Severity = DiagnosticSeverity.Warning, + Message = "Using the symbol 'DateTimeOffset.implicit operator DateTimeOffset(DateTime)' can result in unpredictable behavior", + Locations = + new[] { + new DiagnosticResultLocation("Test0.cs", 13, 17) + } + }); - DateTimeOffset second = DateTimeOffset.Now; + } - if (first < second) - { - Console.WriteLine(""Time has passed...""); - } + [TestMethod] + public void UsageOfImplicitConversionInComparison_DateTimeOffsetToDateTime_ProducesWarningMessage() + { + string source = @" +using System; +using System.Threading; + +namespace ConsoleApp1 +{ + internal class Program + { + static void Main(string[] args) + { + DateTimeOffset first = DateTimeOffset.Now; + DateTime second = DateTime.Now; + _ = first < second } } }"; @@ -74,12 +103,70 @@ static void Main(string[] args) Message = "Using the symbol 'DateTimeOffset.implicit operator DateTimeOffset(DateTime)' can result in unpredictable behavior", Locations = new[] { - new DiagnosticResultLocation("Test0.cs", 17, 17) + new DiagnosticResultLocation("Test0.cs", 13, 25) } }); } + [TestMethod] + public void UsageOfImplicitConversionInComparison_NullableDateTimeOffsetToDateTime_ProducesWarningMessage() + { + string source = @" +using System; +using System.Threading; + +namespace ConsoleApp1 +{ + internal class Program + { + static void Main(string[] args) + { + DateTimeOffset? first = DateTimeOffset.Now; + DateTime second = DateTime.Now; + _ = first < second + } + } +}"; + + VerifyCSharpDiagnostic( + source, + new DiagnosticResult + { + Id = "INTL0202", + Severity = DiagnosticSeverity.Warning, + Message = "Using the symbol 'DateTimeOffset.implicit operator DateTimeOffset(DateTime)' can result in unpredictable behavior", + Locations = new[] { + new DiagnosticResultLocation("Test0.cs", 13, 25) + } + } + ); + + } + + [TestMethod] + public void UsageOfImplicitConversion_InLinq_ProducesWarningMessage() + { + string dir = Directory.GetParent(Environment.CurrentDirectory).Parent.Parent.FullName; + string path = Path.Combine(dir, "Data", "DateTime_ImplicitConversion_InLinq.cs"); + string source = File.ReadAllText(path); + + VerifyCSharpDiagnostic( + source, + new DiagnosticResult + { + Id = "INTL0202", + Severity = DiagnosticSeverity.Warning, + Message = "Using the symbol 'DateTimeOffset.implicit operator DateTimeOffset(DateTime)' can result in unpredictable behavior", + Locations = + new[] { + new DiagnosticResultLocation("Test0.cs", 17, 25) + } + } + ); + } + + [TestMethod] public void UsageOfExplicitConversion_ProducesNothing() { diff --git a/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/IntelliTect.Analyzer.Tests.csproj b/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/IntelliTect.Analyzer.Tests.csproj index 063e1762..75c18afd 100644 --- a/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/IntelliTect.Analyzer.Tests.csproj +++ b/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/IntelliTect.Analyzer.Tests.csproj @@ -5,6 +5,10 @@ CA2007,CA1815,CA1303,CA1707,CA1305 + + + + all