public static void Analyze(SyntaxNodeAnalysisContext context, MemberInvocationExpressionInfo invocationInfo) { SyntaxNode parent = invocationInfo.InvocationExpression.WalkUpParentheses().Parent; if (parent.Kind() != SyntaxKind.LogicalNotExpression) { return; } SingleParameterLambdaExpressionInfo lambdaInfo = SyntaxInfo.SingleParameterLambdaExpressionInfo(invocationInfo.Arguments.First().Expression.WalkDownParentheses()); if (!lambdaInfo.Success) { return; } ExpressionSyntax expression = GetReturnExpression(lambdaInfo.Body)?.WalkDownParentheses(); if (expression?.IsKind(SyntaxKind.LogicalNotExpression) != true) { return; } if (!context.SemanticModel.TryGetExtensionMethodInfo(invocationInfo.InvocationExpression, out MethodInfo methodInfo, ExtensionMethodKind.Reduced, context.CancellationToken)) { return; } if (!methodInfo.IsLinqExtensionOfIEnumerableOfTWithPredicate()) { return; } context.ReportDiagnostic(DiagnosticDescriptors.SimplifyLogicalNegation, parent); }
private static ExpressionSyntax GetNewNode(PrefixUnaryExpressionSyntax logicalNot) { ExpressionSyntax operand = logicalNot.Operand; ExpressionSyntax expression = operand.WalkDownParentheses(); switch (expression.Kind()) { case SyntaxKind.TrueLiteralExpression: case SyntaxKind.FalseLiteralExpression: { LiteralExpressionSyntax newNode = BooleanLiteralExpression(expression.Kind() == SyntaxKind.FalseLiteralExpression); newNode = newNode.WithTriviaFrom(expression); return(operand.ReplaceNode(expression, newNode)); } case SyntaxKind.LogicalNotExpression: { return(((PrefixUnaryExpressionSyntax)expression).Operand); } case SyntaxKind.EqualsExpression: { var equalsExpression = (BinaryExpressionSyntax)expression; BinaryExpressionSyntax notEqualsExpression = NotEqualsExpression( equalsExpression.Left, SyntaxFactory.Token(SyntaxKind.ExclamationEqualsToken).WithTriviaFrom(equalsExpression.OperatorToken), equalsExpression.Right); return(operand.ReplaceNode(equalsExpression, notEqualsExpression)); } case SyntaxKind.InvocationExpression: { var invocationExpression = (InvocationExpressionSyntax)expression; var memberAccessExpression = (MemberAccessExpressionSyntax)invocationExpression.Expression; ExpressionSyntax lambdaExpression = invocationExpression.ArgumentList.Arguments.First().Expression.WalkDownParentheses(); SingleParameterLambdaExpressionInfo lambdaInfo = SyntaxInfo.SingleParameterLambdaExpressionInfo(lambdaExpression); var logicalNot2 = (PrefixUnaryExpressionSyntax)SimplifyLogicalNegationAnalyzer.GetReturnExpression(lambdaInfo.Body).WalkDownParentheses(); InvocationExpressionSyntax newNode = invocationExpression.ReplaceNode(logicalNot2, logicalNot2.Operand.WithTriviaFrom(logicalNot2)); return(SyntaxRefactorings.ChangeInvokedMethodName(newNode, (memberAccessExpression.Name.Identifier.ValueText == "All") ? "Any" : "All")); } } return(null); }
internal static void AnalyzeInvocationExpression(SyntaxNodeAnalysisContext context) { var invocationExpression = (InvocationExpressionSyntax)context.Node; if (!invocationExpression.ContainsDiagnostics && !invocationExpression.SpanContainsDirectives()) { MemberInvocationExpressionInfo invocationInfo = SyntaxInfo.MemberInvocationExpressionInfo(invocationExpression); if (invocationInfo.Success && invocationInfo.NameText == "Any") { ArgumentSyntax argument1 = invocationInfo.Arguments.SingleOrDefault(shouldthrow: false); if (argument1 != null) { MemberInvocationExpressionInfo invocationInfo2 = SyntaxInfo.MemberInvocationExpressionInfo(invocationInfo.Expression); if (invocationInfo2.Success && invocationInfo2.NameText == "Where") { ArgumentSyntax argument2 = invocationInfo2.Arguments.SingleOrDefault(shouldthrow: false); if (argument2 != null) { SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; if (semanticModel.TryGetExtensionMethodInfo(invocationExpression, out MethodInfo methodInfo, ExtensionMethodKind.None, cancellationToken) && methodInfo.IsLinqExtensionOfIEnumerableOfTWithPredicate("Any") && semanticModel.TryGetExtensionMethodInfo(invocationInfo2.InvocationExpression, out MethodInfo methodInfo2, ExtensionMethodKind.None, cancellationToken) && methodInfo2.IsLinqWhere(allowImmutableArrayExtension: true)) { SingleParameterLambdaExpressionInfo lambda = SyntaxInfo.SingleParameterLambdaExpressionInfo(argument1.Expression); if (lambda.Success && lambda.Body is ExpressionSyntax) { SingleParameterLambdaExpressionInfo lambda2 = SyntaxInfo.SingleParameterLambdaExpressionInfo(argument2.Expression); if (lambda2.Success && lambda2.Body is ExpressionSyntax && lambda.ParameterName.Equals(lambda2.ParameterName, StringComparison.Ordinal)) { context.ReportDiagnostic( DiagnosticDescriptors.SimplifyLinqMethodChain, Location.Create(context.SyntaxTree(), TextSpan.FromBounds(invocationInfo2.Name.SpanStart, invocationExpression.Span.End))); } } } } } } } } }
public static Task <Document> RefactorAsync( Document document, InvocationExpressionSyntax invocationExpression, CancellationToken cancellationToken) { MemberInvocationExpressionInfo invocationInfo = SyntaxInfo.MemberInvocationExpressionInfo(invocationExpression); MemberInvocationExpressionInfo invocationInfo2 = SyntaxInfo.MemberInvocationExpressionInfo(invocationInfo.Expression); SingleParameterLambdaExpressionInfo lambda = SyntaxInfo.SingleParameterLambdaExpressionInfo((LambdaExpressionSyntax)invocationInfo.Arguments.First().Expression); SingleParameterLambdaExpressionInfo lambda2 = SyntaxInfo.SingleParameterLambdaExpressionInfo((LambdaExpressionSyntax)invocationInfo2.Arguments.First().Expression); BinaryExpressionSyntax logicalAnd = CSharpFactory.LogicalAndExpression( ((ExpressionSyntax)lambda2.Body).Parenthesize(), ((ExpressionSyntax)lambda.Body).Parenthesize()); InvocationExpressionSyntax newNode = invocationInfo2.InvocationExpression .ReplaceNode(invocationInfo2.Name, invocationInfo.Name.WithTriviaFrom(invocationInfo2.Name)) .WithArgumentList(invocationInfo2.ArgumentList.ReplaceNode((ExpressionSyntax)lambda2.Body, logicalAnd)); return(document.ReplaceNodeAsync(invocationExpression, newNode, cancellationToken)); }
private static Task <Document> CombineEnumerableWhereAndAnyAsync( Document document, InvocationExpressionSyntax invocationExpression, CancellationToken cancellationToken) { SimpleMemberInvocationExpressionInfo invocationInfo = SimpleMemberInvocationExpressionInfo(invocationExpression); SimpleMemberInvocationExpressionInfo invocationInfo2 = SimpleMemberInvocationExpressionInfo(invocationInfo.Expression); SingleParameterLambdaExpressionInfo lambda = SingleParameterLambdaExpressionInfo((LambdaExpressionSyntax)invocationInfo.Arguments.First().Expression); SingleParameterLambdaExpressionInfo lambda2 = SingleParameterLambdaExpressionInfo((LambdaExpressionSyntax)invocationInfo2.Arguments.First().Expression); BinaryExpressionSyntax logicalAnd = LogicalAndExpression( ((ExpressionSyntax)lambda2.Body).Parenthesize(), ((ExpressionSyntax)lambda.Body).Parenthesize()); InvocationExpressionSyntax newNode = invocationInfo2.InvocationExpression .ReplaceNode(invocationInfo2.Name, invocationInfo.Name.WithTriviaFrom(invocationInfo2.Name)) .WithArgumentList(invocationInfo2.ArgumentList.ReplaceNode((ExpressionSyntax)lambda2.Body, logicalAnd)); return(document.ReplaceNodeAsync(invocationExpression, newNode, cancellationToken)); }
public static void AnalyzeWhereAndAny(SyntaxNodeAnalysisContext context) { var invocationExpression = (InvocationExpressionSyntax)context.Node; if (invocationExpression.ContainsDiagnostics) { return; } if (invocationExpression.SpanContainsDirectives()) { return; } SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocationExpression); if (!invocationInfo.Success) { return; } if (invocationInfo.NameText != "Any") { return; } ArgumentSyntax argument1 = invocationInfo.Arguments.SingleOrDefault(shouldThrow: false); if (argument1 == null) { return; } SimpleMemberInvocationExpressionInfo invocationInfo2 = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocationInfo.Expression); if (!invocationInfo2.Success) { return; } if (invocationInfo2.NameText != "Where") { return; } ArgumentSyntax argument2 = invocationInfo2.Arguments.SingleOrDefault(shouldThrow: false); if (argument2 == null) { return; } SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; IMethodSymbol methodSymbol = semanticModel.GetExtensionMethodInfo(invocationExpression, cancellationToken).Symbol; if (methodSymbol == null) { return; } if (!SymbolUtility.IsLinqExtensionOfIEnumerableOfTWithPredicate(methodSymbol, semanticModel, "Any")) { return; } IMethodSymbol methodSymbol2 = semanticModel.GetExtensionMethodInfo(invocationInfo2.InvocationExpression, cancellationToken).Symbol; if (methodSymbol2 == null) { return; } if (!SymbolUtility.IsLinqWhere(methodSymbol2, semanticModel, allowImmutableArrayExtension: true)) { return; } SingleParameterLambdaExpressionInfo lambda = SyntaxInfo.SingleParameterLambdaExpressionInfo(argument1.Expression); if (!lambda.Success) { return; } if (!(lambda.Body is ExpressionSyntax)) { return; } SingleParameterLambdaExpressionInfo lambda2 = SyntaxInfo.SingleParameterLambdaExpressionInfo(argument2.Expression); if (!lambda2.Success) { return; } if (!(lambda2.Body is ExpressionSyntax)) { return; } if (!lambda.Parameter.Identifier.ValueText.Equals(lambda2.Parameter.Identifier.ValueText, StringComparison.Ordinal)) { return; } context.ReportDiagnostic( DiagnosticDescriptors.SimplifyLinqMethodChain, Location.Create(invocationExpression.SyntaxTree, TextSpan.FromBounds(invocationInfo2.Name.SpanStart, invocationExpression.Span.End))); }
private static ExpressionSyntax GetNewNode(PrefixUnaryExpressionSyntax logicalNot, Document document) { ExpressionSyntax operand = logicalNot.Operand; ExpressionSyntax expression = operand.WalkDownParentheses(); switch (expression.Kind()) { case SyntaxKind.TrueLiteralExpression: case SyntaxKind.FalseLiteralExpression: { LiteralExpressionSyntax newNode = BooleanLiteralExpression(expression.Kind() == SyntaxKind.FalseLiteralExpression); newNode = newNode.WithTriviaFrom(expression); return(operand.ReplaceNode(expression, newNode)); } case SyntaxKind.LogicalNotExpression: { return(((PrefixUnaryExpressionSyntax)expression).Operand); } case SyntaxKind.EqualsExpression: case SyntaxKind.NotEqualsExpression: case SyntaxKind.LessThanExpression: case SyntaxKind.LessThanOrEqualExpression: case SyntaxKind.GreaterThanExpression: case SyntaxKind.GreaterThanOrEqualExpression: { BinaryExpressionSyntax newExpression = SyntaxLogicalInverter.GetInstance(document).InvertBinaryExpression((BinaryExpressionSyntax)expression); return(operand.ReplaceNode(expression, newExpression)); } case SyntaxKind.InvocationExpression: { var invocationExpression = (InvocationExpressionSyntax)expression; var memberAccessExpression = (MemberAccessExpressionSyntax)invocationExpression.Expression; ExpressionSyntax lambdaExpression = invocationExpression.ArgumentList.Arguments[0].Expression.WalkDownParentheses(); SingleParameterLambdaExpressionInfo lambdaInfo = SyntaxInfo.SingleParameterLambdaExpressionInfo(lambdaExpression); var logicalNot2 = (PrefixUnaryExpressionSyntax)SimplifyLogicalNegationAnalyzer.GetReturnExpression(lambdaInfo.Body).WalkDownParentheses(); InvocationExpressionSyntax newNode = invocationExpression.ReplaceNode(logicalNot2, logicalNot2.Operand.WithTriviaFrom(logicalNot2)); return(SyntaxRefactorings.ChangeInvokedMethodName(newNode, (memberAccessExpression.Name.Identifier.ValueText == "All") ? "Any" : "All")); } case SyntaxKind.IsPatternExpression: { var isPatternExpression = (IsPatternExpressionSyntax)expression; var pattern = (ConstantPatternSyntax)isPatternExpression.Pattern; UnaryPatternSyntax newPattern = NotPattern(pattern.WithoutTrivia()).WithTriviaFrom(pattern); return(isPatternExpression.WithPattern(newPattern) .PrependToLeadingTrivia(logicalNot.GetLeadingTrivia()) .AppendToTrailingTrivia(logicalNot.GetTrailingTrivia())); } } return(null); }
public static void Analyze( SyntaxNodeAnalysisContext context, MemberInvocationExpressionInfo invocationInfo) { InvocationExpressionSyntax invocationExpression = invocationInfo.InvocationExpression; TextSpan span = TextSpan.FromBounds(invocationInfo.Name.Span.Start, invocationExpression.Span.End); if (invocationExpression.ContainsDirectives(span)) { return; } SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; var methodSymbol = semanticModel.GetSymbol(invocationExpression, cancellationToken) as IMethodSymbol; if (methodSymbol == null) { return; } if (!ExtensionMethodInfo.TryCreate(methodSymbol, semanticModel, out ExtensionMethodInfo extensionMethodInfo)) { return; } if (!extensionMethodInfo.MethodInfo.IsLinqSelect(allowImmutableArrayExtension: true)) { return; } ITypeSymbol typeArgument = extensionMethodInfo.ReducedSymbolOrSymbol.TypeArguments[0]; if (!typeArgument.IsReferenceType) { return; } if (typeArgument.SpecialType == SpecialType.System_Object) { return; } ExpressionSyntax expression = invocationExpression.ArgumentList?.Arguments.Last().Expression; SingleParameterLambdaExpressionInfo lambdaInfo = SyntaxInfo.SingleParameterLambdaExpressionInfo(expression); if (!lambdaInfo.Success) { return; } CastExpressionSyntax castExpression = GetCastExpression(lambdaInfo.Body); if (castExpression == null) { return; } if (!(castExpression.Expression is IdentifierNameSyntax identifierName)) { return; } if (!string.Equals(lambdaInfo.Parameter.Identifier.ValueText, identifierName.Identifier.ValueText, StringComparison.Ordinal)) { return; } var castSymbol = semanticModel.GetSymbol(castExpression, cancellationToken) as IMethodSymbol; if (castSymbol?.MethodKind == MethodKind.Conversion) { return; } context.ReportDiagnostic( DiagnosticDescriptors.CallCastInsteadOfSelect, Location.Create(invocationExpression.SyntaxTree, span)); }