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); }
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)); }
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); }); } } } }