private static bool TryGetReceiverTypeSymbol(
            SyntaxContext syntaxContext,
            ISyntaxFactsService syntaxFacts,
            CancellationToken cancellationToken,
            [NotNullWhen(true)] out ITypeSymbol?receiverTypeSymbol)
        {
            var parentNode = syntaxContext.TargetToken.Parent;

            // Even though implicit access to extension method is allowed, we decide not support it for simplicity
            // e.g. we will not provide completion for unimported extension method in this case
            // New Bar() {.X = .$$ }
            var expressionNode = syntaxFacts.GetLeftSideOfDot(parentNode, allowImplicitTarget: false);

            if (expressionNode != null)
            {
                // Check if we are accessing members of a type, no extension methods are exposed off of types.
                if (syntaxContext.SemanticModel.GetSymbolInfo(expressionNode, cancellationToken).GetAnySymbol() is not ITypeSymbol)
                {
                    // The expression we're calling off of needs to have an actual instance type.
                    // We try to be more tolerant to errors here so completion would still be available in certain case of partially typed code.
                    receiverTypeSymbol = syntaxContext.SemanticModel.GetTypeInfo(expressionNode, cancellationToken).Type;
                    if (receiverTypeSymbol is IErrorTypeSymbol errorTypeSymbol)
                    {
                        receiverTypeSymbol = errorTypeSymbol.CandidateSymbols.Select(GetSymbolType).FirstOrDefault(s => s != null);
                    }

                    return(receiverTypeSymbol != null);
                }
            }

            receiverTypeSymbol = null;
            return(false);
        }