private static RegisterFixData <TArgumentSyntax> TryGetInvocationExpressionFixInfo(
            SemanticModel semanticModel,
            ISyntaxFactsService syntaxFacts,
            SyntaxNode node,
            CancellationToken cancellationToken
            )
        {
            if (node is TInvocationExpressionSyntax invocationExpression)
            {
                var expression = syntaxFacts.GetExpressionOfInvocationExpression(
                    invocationExpression
                    );
                var candidates = semanticModel
                                 .GetMemberGroup(expression, cancellationToken)
                                 .OfType <IMethodSymbol>()
                                 .ToImmutableArray();
                var arguments =
                    (SeparatedSyntaxList <TArgumentSyntax>)syntaxFacts.GetArgumentsOfInvocationExpression(
                        invocationExpression
                        );

                // In VB a constructor calls other constructor overloads via a Me.New(..) invocation.
                // If the candidates are MethodKind.Constructor than these are the equivalent the a C# ConstructorInitializer.
                var isConstructorInitializer = candidates.All(
                    m => m.MethodKind == MethodKind.Constructor
                    );
                return(new RegisterFixData <TArgumentSyntax>(
                           arguments,
                           candidates,
                           isConstructorInitializer
                           ));
            }

            return(null);
        }
Example #2
0
        private static SyntaxNode Unwrap(ISyntaxFactsService syntaxFacts, SyntaxNode node)
        {
            var invocation = node as TInvocationExpression;

            if (invocation != null)
            {
                return(syntaxFacts.GetExpressionOfInvocationExpression(invocation));
            }

            var memberAccess = node as TMemberAccessExpression;

            if (memberAccess != null)
            {
                return(syntaxFacts.GetExpressionOfMemberAccessExpression(memberAccess));
            }

            var conditionalAccess = node as TConditionalAccessExpression;

            if (conditionalAccess != null)
            {
                return(syntaxFacts.GetExpressionOfConditionalAccessExpression(conditionalAccess));
            }

            var elementAccess = node as TElementAccessExpression;

            if (elementAccess != null)
            {
                return(syntaxFacts.GetExpressionOfElementAccessExpression(elementAccess));
            }

            return(null);
        }
        private static bool TryAnalyzeInvocationCondition(
            SyntaxNodeAnalysisContext context,
            ISyntaxFactsService syntaxFacts,
            IMethodSymbol?referenceEqualsMethodOpt,
            TInvocationExpression invocation,
            [NotNullWhen(true)] out SyntaxNode?conditionPartToCheck,
            out bool isEquals)
        {
            conditionPartToCheck = null;
            isEquals             = true;

            var expression = syntaxFacts.GetExpressionOfInvocationExpression(invocation);
            var nameNode   = syntaxFacts.IsIdentifierName(expression)
                ? expression
                : syntaxFacts.IsSimpleMemberAccessExpression(expression)
                    ? syntaxFacts.GetNameOfMemberAccessExpression(expression)
                    : null;

            if (!syntaxFacts.IsIdentifierName(nameNode))
            {
                return(false);
            }

            syntaxFacts.GetNameAndArityOfSimpleName(nameNode, out var name, out _);
            if (!syntaxFacts.StringComparer.Equals(name, nameof(ReferenceEquals)))
            {
                return(false);
            }

            var arguments = syntaxFacts.GetArgumentsOfInvocationExpression(invocation);

            if (arguments.Count != 2)
            {
                return(false);
            }

            var conditionLeft  = syntaxFacts.GetExpressionOfArgument(arguments[0]);
            var conditionRight = syntaxFacts.GetExpressionOfArgument(arguments[1]);

            if (conditionLeft == null || conditionRight == null)
            {
                return(false);
            }

            conditionPartToCheck = GetConditionPartToCheck(syntaxFacts, conditionLeft, conditionRight);
            if (conditionPartToCheck == null)
            {
                return(false);
            }

            var semanticModel     = context.SemanticModel;
            var cancellationToken = context.CancellationToken;
            var symbol            = semanticModel.GetSymbolInfo(invocation, cancellationToken).Symbol;

            return(referenceEqualsMethodOpt != null && referenceEqualsMethodOpt.Equals(symbol));
        }
Example #4
0
        private bool TryAnalyzeAddInvocation(
            TExpressionStatementSyntax statement,
            out SyntaxNode instance)
        {
            instance = null;
            var invocationExpression = _syntaxFacts.GetExpressionOfExpressionStatement(statement) as TInvocationExpressionSyntax;

            if (invocationExpression == null)
            {
                return(false);
            }

            var arguments = _syntaxFacts.GetArgumentsOfInvocationExpression(invocationExpression);

            if (arguments.Count < 1)
            {
                return(false);
            }

            foreach (var argument in arguments)
            {
                if (!_syntaxFacts.IsSimpleArgument(argument))
                {
                    return(false);
                }
            }

            var memberAccess = _syntaxFacts.GetExpressionOfInvocationExpression(invocationExpression) as TMemberAccessExpressionSyntax;

            if (memberAccess == null)
            {
                return(false);
            }

            if (!_syntaxFacts.IsSimpleMemberAccessExpression(memberAccess))
            {
                return(false);
            }

            SyntaxNode memberName;

            _syntaxFacts.GetPartsOfMemberAccessExpression(memberAccess, out instance, out memberName);

            string name;
            int    arity;

            _syntaxFacts.GetNameAndArityOfSimpleName(memberName, out name, out arity);

            if (arity != 0 || !name.Equals(nameof(IList.Add)))
            {
                return(false);
            }

            return(true);
        }
        private static SyntaxNode Unwrap(ISyntaxFactsService syntaxFacts, SyntaxNode node)
        {
            if (node is TInvocationExpression invocation)
            {
                return(syntaxFacts.GetExpressionOfInvocationExpression(invocation));
            }

            if (node is TMemberAccessExpression memberAccess)
            {
                return(syntaxFacts.GetExpressionOfMemberAccessExpression(memberAccess));
            }

            if (node is TConditionalAccessExpression conditionalAccess)
            {
                return(syntaxFacts.GetExpressionOfConditionalAccessExpression(conditionalAccess));
            }

            if (node is TElementAccessExpression elementAccess)
            {
                return(syntaxFacts.GetExpressionOfElementAccessExpression(elementAccess));
            }

            return(null);
        }
        private static void RemoveAwaitFromCallerIfPresent(
            SyntaxEditor editor, ISyntaxFactsService syntaxFacts,
            SyntaxNode root, ReferenceLocation referenceLocation,
            CancellationToken cancellationToken)
        {
            if (referenceLocation.IsImplicit)
            {
                return;
            }

            var location = referenceLocation.Location;
            var token    = location.FindToken(cancellationToken);

            var nameNode = token.Parent;

            if (nameNode == null)
            {
                return;
            }

            // Look for the following forms:
            //  await M(...)
            //  await <expr>.M(...)
            //  await M(...).ConfigureAwait(...)
            //  await <expr>.M(...).ConfigureAwait(...)

            var expressionNode = nameNode;

            if (syntaxFacts.IsNameOfMemberAccessExpression(nameNode))
            {
                expressionNode = nameNode.Parent;
            }

            if (!syntaxFacts.IsExpressionOfInvocationExpression(expressionNode))
            {
                return;
            }

            // We now either have M(...) or <expr>.M(...)

            var invocationExpression = expressionNode.Parent;

            Debug.Assert(syntaxFacts.IsInvocationExpression(invocationExpression));

            if (syntaxFacts.IsExpressionOfAwaitExpression(invocationExpression))
            {
                // Handle the case where we're directly awaited.
                var awaitExpression = invocationExpression.Parent;
                editor.ReplaceNode(awaitExpression, (currentAwaitExpression, generator) =>
                                   syntaxFacts.GetExpressionOfAwaitExpression(currentAwaitExpression)
                                   .WithTriviaFrom(currentAwaitExpression));
            }
            else if (syntaxFacts.IsExpressionOfMemberAccessExpression(invocationExpression))
            {
                // Check for the .ConfigureAwait case.
                var parentMemberAccessExpression         = invocationExpression.Parent;
                var parentMemberAccessExpressionNameNode = syntaxFacts.GetNameOfMemberAccessExpression(
                    parentMemberAccessExpression);

                var parentMemberAccessExpressionName = syntaxFacts.GetIdentifierOfSimpleName(parentMemberAccessExpressionNameNode).ValueText;
                if (parentMemberAccessExpressionName == nameof(Task.ConfigureAwait))
                {
                    var parentExpression = parentMemberAccessExpression.Parent;
                    if (syntaxFacts.IsExpressionOfAwaitExpression(parentExpression))
                    {
                        var awaitExpression = parentExpression.Parent;
                        editor.ReplaceNode(awaitExpression, (currentAwaitExpression, generator) =>
                        {
                            var currentConfigureAwaitInvocation = syntaxFacts.GetExpressionOfAwaitExpression(currentAwaitExpression);
                            var currentMemberAccess             = syntaxFacts.GetExpressionOfInvocationExpression(currentConfigureAwaitInvocation);
                            var currentInvocationExpression     = syntaxFacts.GetExpressionOfMemberAccessExpression(currentMemberAccess);
                            return(currentInvocationExpression.WithTriviaFrom(currentAwaitExpression));
                        });
                    }
                }
            }
        }
        private void RemoveAwaitFromCallerIfPresent(
            SyntaxEditor editor, ISyntaxFactsService syntaxFacts, 
            SyntaxNode root, ReferenceLocation referenceLocation,
            CancellationToken cancellationToken)
        {
            if (referenceLocation.IsImplicit)
            {
                return;
            }

            var location = referenceLocation.Location;
            var token = location.FindToken(cancellationToken);

            var nameNode = token.Parent;
            if (nameNode == null)
            {
                return;
            }

            // Look for the following forms:
            //  await M(...)
            //  await <expr>.M(...)
            //  await M(...).ConfigureAwait(...)
            //  await <expr>.M(...).ConfigureAwait(...)

            var expressionNode = nameNode;
            if (syntaxFacts.IsNameOfMemberAccessExpression(nameNode))
            {
                expressionNode = nameNode.Parent;
            }

            if (!syntaxFacts.IsExpressionOfInvocationExpression(expressionNode))
            {
                return;
            }

            // We now either have M(...) or <expr>.M(...)

            var invocationExpression = expressionNode.Parent;
            Debug.Assert(syntaxFacts.IsInvocationExpression(invocationExpression));

            if (syntaxFacts.IsExpressionOfAwaitExpression(invocationExpression))
            {
                // Handle the case where we're directly awaited.  
                var awaitExpression = invocationExpression.Parent;
                editor.ReplaceNode(awaitExpression, (currentAwaitExpression, generator) =>
                    syntaxFacts.GetExpressionOfAwaitExpression(currentAwaitExpression)
                               .WithTriviaFrom(currentAwaitExpression));
            }
            else if (syntaxFacts.IsExpressionOfMemberAccessExpression(invocationExpression))
            {
                // Check for the .ConfigureAwait case.
                var parentMemberAccessExpression = invocationExpression.Parent;
                var parentMemberAccessExpressionNameNode = syntaxFacts.GetNameOfMemberAccessExpression(
                    parentMemberAccessExpression);

                var parentMemberAccessExpressionName = syntaxFacts.GetIdentifierOfSimpleName(parentMemberAccessExpressionNameNode).ValueText;
                if (parentMemberAccessExpressionName == nameof(Task.ConfigureAwait))
                {
                    var parentExpression = parentMemberAccessExpression.Parent;
                    if (syntaxFacts.IsExpressionOfAwaitExpression(parentExpression))
                    {
                        var awaitExpression = parentExpression.Parent;
                        editor.ReplaceNode(awaitExpression, (currentAwaitExpression, generator) =>
                        {
                            var currentConfigureAwaitInvocation = syntaxFacts.GetExpressionOfAwaitExpression(currentAwaitExpression);
                            var currentMemberAccess = syntaxFacts.GetExpressionOfInvocationExpression(currentConfigureAwaitInvocation);
                            var currentInvocationExpression = syntaxFacts.GetExpressionOfMemberAccessExpression(currentMemberAccess);
                            return currentInvocationExpression.WithTriviaFrom(currentAwaitExpression);
                        });
                    }
                }
            }
        }