private static bool IsVariableAwaitedOrJoined()

in src/Microsoft.VisualStudio.SDK.Analyzers/VSSDK007ThreadHelperJTFRunAsync.cs [238:308]


        private static bool IsVariableAwaitedOrJoined(SyntaxNodeAnalysisContext context, string variableName, SyntaxNode enclosingBlock)
        {
            // No diagnostic for:  await task;
            IEnumerable<AwaitExpressionSyntax>? awaitedList = from awaitExpr in enclosingBlock.DescendantNodes().OfType<AwaitExpressionSyntax>()
                              where awaitExpr.ChildNodes().OfType<IdentifierNameSyntax>().Count() == 1 &&
                                    awaitExpr.ChildNodes().OfType<IdentifierNameSyntax>().Single().Identifier.ValueText == variableName
                              select awaitExpr;

            if (awaitedList.Any())
            {
                return true;
            }

            // No diagnostic for:  task.Join();
            IEnumerable<IdentifierNameSyntax>? methodCallList = from varMethodCall in enclosingBlock.DescendantNodes().OfType<MemberAccessExpressionSyntax>()
                                 where varMethodCall.ChildNodes().OfType<IdentifierNameSyntax>().Count() == 2 &&
                                       varMethodCall.ChildNodes().OfType<IdentifierNameSyntax>().First().Identifier.ValueText == variableName
                                 select varMethodCall.ChildNodes().OfType<IdentifierNameSyntax>().ElementAt(1);

            foreach (IdentifierNameSyntax? method in methodCallList)
            {
                if (method.Identifier.ValueText == Types.JoinableTask.Join)
                {
                    return true;
                }
            }

            // No diagnostic for:  await task.JoinAsync();
            IEnumerable<AwaitExpressionSyntax>? awaitedJoinAsyncList = from awaitExpr in enclosingBlock.DescendantNodes().OfType<AwaitExpressionSyntax>()
                                       where VariableAwaitsJoinAsyncMethod(variableName, awaitExpr)
                                       select awaitExpr;

            if (awaitedJoinAsyncList.Any())
            {
                return true;
            }

            // Find any methods that the JoinableTask variable is passed to in case any of these methods performs the join,
            // and recursively search them to determine if they perform the await/join.
            IEnumerable<InvocationExpressionSyntax>? passedToMethodList = enclosingBlock.DescendantNodes().OfType<InvocationExpressionSyntax>();
            foreach (InvocationExpressionSyntax? passedToMethodInvocation in passedToMethodList)
            {
                if (VariablePassedAsArgumentToInvokedMethod(variableName, passedToMethodInvocation, out IdentifierNameSyntax? methodName, out var argIndex) &&
                    methodName != null &&
                    argIndex != null)
                {
                    if (context.SemanticModel.GetSymbolInfo(methodName, context.CancellationToken).Symbol is not IMethodSymbol methodSymbol)
                    {
                        return false;
                    }

                    if (argIndex < methodSymbol.Parameters.Length)
                    {
                        IParameterSymbol? param = methodSymbol.Parameters[argIndex.Value];
                        SyntaxNode? methodEnclosingBlock = GetMethodDeclarationBlockNode(methodSymbol);
                        if (methodEnclosingBlock == null)
                        {
                            return false;
                        }

                        // Is the parameter awaited/joined inside the method?
                        if (IsVariableAwaitedOrJoined(context, param.Name, methodEnclosingBlock))
                        {
                            return true;
                        }
                    }
                }
            }

            return false;
        }