@@ -1868,7 +1868,7 @@ internal sealed class CompletedTaskAttribute : System.Attribute
18681868
18691869class Tests
18701870{
1871- [Microsoft.VisualStudio.Threading.CompletedTask]
1871+ [{|#0: Microsoft.VisualStudio.Threading.CompletedTask|} ]
18721872 private static Task MyTask = Task.CompletedTask; // Not readonly
18731873
18741874 async Task GetTask()
@@ -1877,7 +1877,10 @@ async Task GetTask()
18771877 }
18781878}
18791879" ;
1880- await CSVerify . VerifyAnalyzerAsync ( test ) ;
1880+ DiagnosticResult expected = new DiagnosticResult ( Microsoft . VisualStudio . Threading . Analyzers . VSTHRD003UseJtfRunAsyncAnalyzer . InvalidAttributeUseDescriptor )
1881+ . WithLocation ( 0 )
1882+ . WithArguments ( "Fields must be readonly." ) ;
1883+ await CSVerify . VerifyAnalyzerAsync ( test , expected ) ;
18811884 }
18821885
18831886 [ Fact ]
@@ -1896,7 +1899,7 @@ internal sealed class CompletedTaskAttribute : System.Attribute
18961899
18971900class Tests
18981901{
1899- [Microsoft.VisualStudio.Threading.CompletedTask]
1902+ [{|#0: Microsoft.VisualStudio.Threading.CompletedTask|} ]
19001903 public static Task MyTask { get; set; } = Task.CompletedTask; // Public setter
19011904
19021905 async Task GetTask()
@@ -1905,7 +1908,10 @@ async Task GetTask()
19051908 }
19061909}
19071910" ;
1908- await CSVerify . VerifyAnalyzerAsync ( test ) ;
1911+ DiagnosticResult expected = new DiagnosticResult ( Microsoft . VisualStudio . Threading . Analyzers . VSTHRD003UseJtfRunAsyncAnalyzer . InvalidAttributeUseDescriptor )
1912+ . WithLocation ( 0 )
1913+ . WithArguments ( "Properties must not have non-private setters." ) ;
1914+ await CSVerify . VerifyAnalyzerAsync ( test , expected ) ;
19091915 }
19101916
19111917 [ Fact ]
@@ -1924,7 +1930,7 @@ internal sealed class CompletedTaskAttribute : System.Attribute
19241930
19251931class Tests
19261932{
1927- [Microsoft.VisualStudio.Threading.CompletedTask]
1933+ [{|#0: Microsoft.VisualStudio.Threading.CompletedTask|} ]
19281934 public static Task MyTask { get; internal set; } = Task.CompletedTask; // Internal setter
19291935
19301936 async Task GetTask()
@@ -1933,7 +1939,10 @@ async Task GetTask()
19331939 }
19341940}
19351941" ;
1936- await CSVerify . VerifyAnalyzerAsync ( test ) ;
1942+ DiagnosticResult expected = new DiagnosticResult ( Microsoft . VisualStudio . Threading . Analyzers . VSTHRD003UseJtfRunAsyncAnalyzer . InvalidAttributeUseDescriptor )
1943+ . WithLocation ( 0 )
1944+ . WithArguments ( "Properties must not have non-private setters." ) ;
1945+ await CSVerify . VerifyAnalyzerAsync ( test , expected ) ;
19371946 }
19381947
19391948 [ Fact ]
@@ -1992,6 +2001,158 @@ async Task GetTask()
19922001 await CSVerify . VerifyAnalyzerAsync ( test ) ;
19932002 }
19942003
2004+ [ Fact ]
2005+ public async Task ReportDiagnosticWhenCompletedTaskAttributeOnPropertyWithPublicInit ( )
2006+ {
2007+ var test = @"
2008+ using System.Threading.Tasks;
2009+
2010+ namespace Microsoft.VisualStudio.Threading
2011+ {
2012+ [System.AttributeUsage(System.AttributeTargets.Property | System.AttributeTargets.Method | System.AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
2013+ internal sealed class CompletedTaskAttribute : System.Attribute
2014+ {
2015+ }
2016+ }
2017+
2018+ class Tests
2019+ {
2020+ [{|#0:Microsoft.VisualStudio.Threading.CompletedTask|}]
2021+ public static Task MyTask { get; init; } = Task.CompletedTask; // Public init
2022+
2023+ async Task GetTask()
2024+ {
2025+ await [|MyTask|];
2026+ }
2027+ }
2028+ " ;
2029+ DiagnosticResult expected = new DiagnosticResult ( Microsoft . VisualStudio . Threading . Analyzers . VSTHRD003UseJtfRunAsyncAnalyzer . InvalidAttributeUseDescriptor )
2030+ . WithLocation ( 0 )
2031+ . WithArguments ( "Properties with init accessors must be private." ) ;
2032+ await CSVerify . VerifyAnalyzerAsync ( test , expected ) ;
2033+ }
2034+
2035+ [ Fact ]
2036+ public async Task DoNotReportWarningWhenCompletedTaskAttributeOnPrivatePropertyWithInit ( )
2037+ {
2038+ var test = @"
2039+ using System.Threading.Tasks;
2040+
2041+ namespace Microsoft.VisualStudio.Threading
2042+ {
2043+ [System.AttributeUsage(System.AttributeTargets.Property | System.AttributeTargets.Method | System.AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
2044+ internal sealed class CompletedTaskAttribute : System.Attribute
2045+ {
2046+ }
2047+ }
2048+
2049+ class Tests
2050+ {
2051+ [Microsoft.VisualStudio.Threading.CompletedTask]
2052+ private static Task MyTask { get; init; } = Task.CompletedTask; // Private init is OK
2053+
2054+ async Task GetTask()
2055+ {
2056+ await MyTask;
2057+ }
2058+ }
2059+ " ;
2060+ await CSVerify . VerifyAnalyzerAsync ( test ) ;
2061+ }
2062+
2063+ [ Fact ]
2064+ public async Task ReportDiagnosticWhenCompletedTaskAttributeOnNonReadonlyFieldWithDiagnosticOnAttribute ( )
2065+ {
2066+ var test = @"
2067+ using System.Threading.Tasks;
2068+
2069+ namespace Microsoft.VisualStudio.Threading
2070+ {
2071+ [System.AttributeUsage(System.AttributeTargets.Property | System.AttributeTargets.Method | System.AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
2072+ internal sealed class CompletedTaskAttribute : System.Attribute
2073+ {
2074+ }
2075+ }
2076+
2077+ class Tests
2078+ {
2079+ [{|#0:Microsoft.VisualStudio.Threading.CompletedTask|}]
2080+ private static Task MyTask = Task.CompletedTask; // Not readonly
2081+
2082+ async Task GetTask()
2083+ {
2084+ await [|MyTask|];
2085+ }
2086+ }
2087+ " ;
2088+ DiagnosticResult expected = new DiagnosticResult ( Microsoft . VisualStudio . Threading . Analyzers . VSTHRD003UseJtfRunAsyncAnalyzer . InvalidAttributeUseDescriptor )
2089+ . WithLocation ( 0 )
2090+ . WithArguments ( "Fields must be readonly." ) ;
2091+ await CSVerify . VerifyAnalyzerAsync ( test , expected ) ;
2092+ }
2093+
2094+ [ Fact ]
2095+ public async Task ReportDiagnosticWhenCompletedTaskAttributeOnPropertyWithPublicSetterWithDiagnosticOnAttribute ( )
2096+ {
2097+ var test = @"
2098+ using System.Threading.Tasks;
2099+
2100+ namespace Microsoft.VisualStudio.Threading
2101+ {
2102+ [System.AttributeUsage(System.AttributeTargets.Property | System.AttributeTargets.Method | System.AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
2103+ internal sealed class CompletedTaskAttribute : System.Attribute
2104+ {
2105+ }
2106+ }
2107+
2108+ class Tests
2109+ {
2110+ [{|#0:Microsoft.VisualStudio.Threading.CompletedTask|}]
2111+ public static Task MyTask { get; set; } = Task.CompletedTask; // Public setter
2112+
2113+ async Task GetTask()
2114+ {
2115+ await [|MyTask|];
2116+ }
2117+ }
2118+ " ;
2119+ DiagnosticResult expected = new DiagnosticResult ( Microsoft . VisualStudio . Threading . Analyzers . VSTHRD003UseJtfRunAsyncAnalyzer . InvalidAttributeUseDescriptor )
2120+ . WithLocation ( 0 )
2121+ . WithArguments ( "Properties must not have non-private setters." ) ;
2122+ await CSVerify . VerifyAnalyzerAsync ( test , expected ) ;
2123+ }
2124+
2125+ [ Fact ]
2126+ public async Task ReportDiagnosticWhenCompletedTaskAttributeOnPropertyWithInternalSetterWithDiagnosticOnAttribute ( )
2127+ {
2128+ var test = @"
2129+ using System.Threading.Tasks;
2130+
2131+ namespace Microsoft.VisualStudio.Threading
2132+ {
2133+ [System.AttributeUsage(System.AttributeTargets.Property | System.AttributeTargets.Method | System.AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
2134+ internal sealed class CompletedTaskAttribute : System.Attribute
2135+ {
2136+ }
2137+ }
2138+
2139+ class Tests
2140+ {
2141+ [{|#0:Microsoft.VisualStudio.Threading.CompletedTask|}]
2142+ public static Task MyTask { get; internal set; } = Task.CompletedTask; // Internal setter
2143+
2144+ async Task GetTask()
2145+ {
2146+ await [|MyTask|];
2147+ }
2148+ }
2149+ " ;
2150+ DiagnosticResult expected = new DiagnosticResult ( Microsoft . VisualStudio . Threading . Analyzers . VSTHRD003UseJtfRunAsyncAnalyzer . InvalidAttributeUseDescriptor )
2151+ . WithLocation ( 0 )
2152+ . WithArguments ( "Properties must not have non-private setters." ) ;
2153+ await CSVerify . VerifyAnalyzerAsync ( test , expected ) ;
2154+ }
2155+
19952156 private DiagnosticResult CreateDiagnostic ( int line , int column , int length ) =>
19962157 CSVerify . Diagnostic ( ) . WithSpan ( line , column , line , column + length ) ;
19972158}
0 commit comments