@@ -70,6 +70,19 @@ public TestMe Nested { get }
70
70
71
71
public bool DoSomething(TestMe arg) => arg != null && arg.Nested != null && arg.Nested.Value == 42;
72
72
}
73
+ " ) ;
74
+
75
+ [ Test ]
76
+ public void No_issue_is_reported_for_class_with_conditional_null_checks_and_value_type_comparison ( ) => No_issue_is_reported_for ( @"
77
+ using System;
78
+
79
+ public class TestMe
80
+ {
81
+ public TestMe Nested { get }
82
+ public int Value { get; }
83
+
84
+ public bool DoSomething(TestMe arg) => arg != null && arg.Nested?.Value == 42;
85
+ }
73
86
" ) ;
74
87
75
88
[ Test ]
@@ -234,6 +247,64 @@ public class TestMe
234
247
235
248
public bool SomeComparison(TestMe other) => other is null || (Value != other.Value && Data != other.Data);
236
249
}
250
+ " ) ;
251
+
252
+ [ Test ]
253
+ public void No_issue_is_reported_for_complex_class_with_value_type_enum_OR_comparison ( ) => No_issue_is_reported_for ( @"
254
+ using System;
255
+ using System.Linq;
256
+
257
+ public class TestMe
258
+ {
259
+ public StringComparison Comparison { get; set; }
260
+
261
+ public Guid Id { get; set; }
262
+
263
+ public bool SomeComparison(TestMe other) => other.Id == Guid.Empty && (other.Comparison == StringComparison.Ordinal || other.Comparison == StringComparison.OrdinalIgnoreCase);
264
+ }
265
+ " ) ;
266
+
267
+ [ Test ]
268
+ public void No_issue_is_reported_for_parameters_only_value_type_comparisons ( ) => No_issue_is_reported_for ( @"
269
+ using System;
270
+
271
+ public class TestMe
272
+ {
273
+ public static bool SomeComparison(Guid guid1, Guid guid2, Guid guid3, Guid guid4) => guid1 == guid3 && guid2 == guid4;
274
+ }
275
+ " ) ;
276
+
277
+ [ Test ]
278
+ public void No_issue_is_reported_for_CancellationToken_IsCancellationRequested_call ( ) => No_issue_is_reported_for ( @"
279
+ using System;
280
+ using System.Threading;
281
+
282
+ public class TestMe
283
+ {
284
+ public static bool SomeComparison(CancellationToken token, int value) => token.IsCancellationRequested || value == -1;
285
+ }
286
+ " ) ;
287
+
288
+ [ Test ]
289
+ public void No_issue_is_reported_for_version_comparison ( ) => No_issue_is_reported_for ( @"
290
+ using System;
291
+ using System.Threading;
292
+
293
+ public class TestMe
294
+ {
295
+ public static bool SomeComparison(Version version) => version.Major == 0 && version.Minor == 0 && version.Build == 0 && version.Revision == 0;
296
+ }
297
+ " ) ;
298
+
299
+ [ Test ]
300
+ public void No_issue_is_reported_for_version_comparison_when_numbers_are_on_left_side ( ) => No_issue_is_reported_for ( @"
301
+ using System;
302
+ using System.Threading;
303
+
304
+ public class TestMe
305
+ {
306
+ public static bool SomeComparison(Version version) => 0 == version.Major && 0 == version.Minor && 0 == version.Build && 0 == version.Revision;
307
+ }
237
308
" ) ;
238
309
239
310
[ Test ]
@@ -339,6 +410,32 @@ public class TestMe
339
410
{
340
411
public bool DoSomething(int i, object o) => o.ToString() == ""whatever"" || i == 42;
341
412
}
413
+ " ) ;
414
+
415
+ [ Test ]
416
+ public void An_issue_is_reported_for_class_with_reference_type_comparison_and_multiple_null_checks_and_value_type_comparison ( ) => An_issue_is_reported_for ( @"
417
+ using System;
418
+
419
+ public class TestMe
420
+ {
421
+ public TestMe Nested { get }
422
+ public int Value { get; }
423
+
424
+ public bool DoSomething(TestMe arg, object o) => o.ToString() == ""whatever"" && arg != null && arg.Nested != null && arg.Nested.Value == 42;
425
+ }
426
+ " ) ;
427
+
428
+ [ Test ]
429
+ public void An_issue_is_reported_for_class_with_conditional_value_type_comparison_and_reference_type_comparison_if_string_invocation_comes_first ( ) => An_issue_is_reported_for ( @"
430
+ using System;
431
+
432
+ public class TestMe
433
+ {
434
+ public TestMe Nested { get }
435
+ public int Value { get; }
436
+
437
+ public bool DoSomething(TestMe arg, object o) => o.ToString() == ""whatever"" && arg?.Nested?.Value == 42;
438
+ }
342
439
" ) ;
343
440
344
441
[ Test ]
@@ -651,7 +748,101 @@ public bool DoSomething(int i, int[] values)
651
748
VerifyCSharpFix ( OriginalText , FixedText ) ;
652
749
}
653
750
654
- //// TODO RKN: Add more complex AND/OR Comparisons with at least 3 comparisons and parenthesized ones
751
+ [ Test ]
752
+ public void Code_gets_fixed_for_class_with_reference_type_comparison_and_multiple_null_checks_and_value_type_comparison ( )
753
+ {
754
+ const string OriginalCode = @"
755
+ using System;
756
+
757
+ public class TestMe
758
+ {
759
+ public TestMe Nested { get }
760
+ public int Value { get; }
761
+
762
+ public bool DoSomething(TestMe arg, object o) => o.ToString() == ""whatever"" && arg != null && arg.Nested != null && arg.Nested.Value == 42;
763
+ }
764
+ " ;
765
+
766
+ const string FixedCode = @"
767
+ using System;
768
+
769
+ public class TestMe
770
+ {
771
+ public TestMe Nested { get }
772
+ public int Value { get; }
773
+
774
+ public bool DoSomething(TestMe arg, object o) => arg != null && arg.Nested != null && arg.Nested.Value == 42 && o.ToString() == ""whatever"";
775
+ }
776
+ " ;
777
+
778
+ VerifyCSharpFix ( OriginalCode , FixedCode ) ;
779
+ }
780
+
781
+ [ Test ]
782
+ public void Code_gets_fixed_for_class_with_conditional_value_type_comparison_and_reference_type_comparison_if_string_invocation_comes_first ( )
783
+ {
784
+ const string OriginalCode = @"
785
+ using System;
786
+
787
+ public class TestMe
788
+ {
789
+ public TestMe Nested { get }
790
+ public int Value { get; }
791
+
792
+ public bool DoSomething(TestMe arg, object o) => o.ToString() == ""whatever"" && arg?.Nested?.Value == 42;
793
+ }
794
+ " ;
795
+
796
+ const string FixedCode = @"
797
+ using System;
798
+
799
+ public class TestMe
800
+ {
801
+ public TestMe Nested { get }
802
+ public int Value { get; }
803
+
804
+ public bool DoSomething(TestMe arg, object o) => arg?.Nested?.Value == 42 && o.ToString() == ""whatever"";
805
+ }
806
+ " ;
807
+
808
+ VerifyCSharpFix ( OriginalCode , FixedCode ) ;
809
+ }
810
+
811
+ [ Test ]
812
+ public void Code_gets_fixed_for_class_with_conditional_value_type_comparison_and_boolean_method_calls_if_method_calls_come_first ( )
813
+ {
814
+ const string OriginalCode = @"
815
+ using System;
816
+
817
+ public class TestMe
818
+ {
819
+ public StringComparison Comparison { get }
820
+
821
+ public bool DoSomething(TestMe t) => IsSomething(t) && FindSomething(t) == t && t.Comparison == StringComparison.Ordinal;
822
+
823
+ public bool IsSomething(object o) => true;
824
+
825
+ public object FindSomething(object o) => o;
826
+ }
827
+ " ;
828
+
829
+ const string FixedCode = @"
830
+ using System;
831
+
832
+ public class TestMe
833
+ {
834
+ public StringComparison Comparison { get }
835
+
836
+ public bool DoSomething(TestMe t) => t.Comparison == StringComparison.Ordinal && IsSomething(t) && FindSomething(t) == t;
837
+
838
+ public bool IsSomething(object o) => true;
839
+
840
+ public object FindSomething(object o) => o;
841
+ }
842
+ " ;
843
+
844
+ VerifyCSharpFix ( OriginalCode , FixedCode ) ;
845
+ }
655
846
656
847
protected override string GetDiagnosticId ( ) => MiKo_5018_LogicalValueComparisonsComeFirstAnalyzer . Id ;
657
848
0 commit comments