diff --git a/src/Microsoft.VisualStudio.Threading.Analyzers.CSharp/CSharpCommonInterest.cs b/src/Microsoft.VisualStudio.Threading.Analyzers.CSharp/CSharpCommonInterest.cs index c3e7d81a6..6525e5e35 100644 --- a/src/Microsoft.VisualStudio.Threading.Analyzers.CSharp/CSharpCommonInterest.cs +++ b/src/Microsoft.VisualStudio.Threading.Analyzers.CSharp/CSharpCommonInterest.cs @@ -176,9 +176,8 @@ private static bool IsTaskCompletedWithWhenAll(SyntaxNodeAnalysisContext context MemberAccessExpressionSyntax? memberAccess = memberAccessList.First(); // Does the invocation have the expected `Task.WhenAll` syntax? This is cheaper to verify before looking up its semantic type. - var correctSyntax = - ((IdentifierNameSyntax)memberAccess.Expression).Identifier.ValueText == Types.Task.TypeName && - ((IdentifierNameSyntax)memberAccess.Name).Identifier.ValueText == Types.Task.WhenAll; + bool correctSyntax = memberAccess.Expression is IdentifierNameSyntax { Identifier.ValueText: Types.Task.TypeName } + && memberAccess.Name is IdentifierNameSyntax { Identifier.ValueText: Types.Task.WhenAll }; if (!correctSyntax) { diff --git a/test/Microsoft.VisualStudio.Threading.Analyzers.Tests/VSTHRD102AvoidJtfRunInNonPublicMembersAnalyzerTests.cs b/test/Microsoft.VisualStudio.Threading.Analyzers.Tests/VSTHRD102AvoidJtfRunInNonPublicMembersAnalyzerTests.cs index 9dd875410..a690f1e03 100644 --- a/test/Microsoft.VisualStudio.Threading.Analyzers.Tests/VSTHRD102AvoidJtfRunInNonPublicMembersAnalyzerTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Analyzers.Tests/VSTHRD102AvoidJtfRunInNonPublicMembersAnalyzerTests.cs @@ -353,6 +353,36 @@ public class Test { public void Advise(Action foo) { } } +"; + await Verify.VerifyAnalyzerAsync(test); + } + + [Fact] + public async Task JtfRunInPrivateMethod__WithMultiMemberAccessExpression_ProducesDiagnostic() + { + var test = @" +using System.Threading.Tasks; +using Microsoft.VisualStudio.Threading; + +class Other { + internal static JoinableTaskFactory factory; +} + +class Test { + Foo foo; + JoinableTaskFactory jtf; + + void F() { + object v = Other.factory.[|Run|](async () => { return await this.foo.DoSomethingAsync(); }); + jtf.[|Run|](async delegate { + await jtf.SwitchToMainThreadAsync(); + }); + } + + class Foo { + internal Task DoSomethingAsync() => new TaskCompletionSource().Task; + } +} "; await Verify.VerifyAnalyzerAsync(test); }