public static bool IsFixable( SimpleMemberInvocationExpressionInfo invocationInfo, SemanticModel semanticModel, CancellationToken cancellationToken) { if (invocationInfo.Expression?.IsMissing != false) { return(false); } IMethodSymbol methodSymbol = semanticModel.GetReducedExtensionMethodInfo(invocationInfo.InvocationExpression, cancellationToken).Symbol; if (methodSymbol == null) { return(false); } if (!SymbolUtility.IsLinqExtensionOfIEnumerableOfTWithoutParameters(methodSymbol, "First", semanticModel, allowImmutableArrayExtension: true)) { return(false); } ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(invocationInfo.Expression, cancellationToken); return(SymbolUtility.HasAccessibleIndexer(typeSymbol, semanticModel, invocationInfo.InvocationExpression.SpanStart)); }
public static void AnalyzeWhere(SyntaxNodeAnalysisContext context, SimpleMemberInvocationExpressionInfo invocationInfo) { SimpleMemberInvocationExpressionInfo invocationInfo2 = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocationInfo.Expression); if (!invocationInfo2.Success) { return; } if (invocationInfo2.Arguments.Count != 1) { return; } if (invocationInfo2.NameText != "Where") { return; } InvocationExpressionSyntax invocation = invocationInfo.InvocationExpression; SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; IMethodSymbol methodSymbol = semanticModel.GetExtensionMethodInfo(invocation, cancellationToken).Symbol; if (methodSymbol == null) { return; } if (!SymbolUtility.IsLinqExtensionOfIEnumerableOfTWithoutParameters(methodSymbol, invocationInfo.NameText, semanticModel)) { return; } IMethodSymbol methodSymbol2 = semanticModel.GetExtensionMethodInfo(invocationInfo2.InvocationExpression, cancellationToken).Symbol; if (methodSymbol2 == null) { return; } if (!SymbolUtility.IsLinqWhere(methodSymbol2, semanticModel, allowImmutableArrayExtension: true)) { return; } TextSpan span = TextSpan.FromBounds(invocationInfo2.Name.SpanStart, invocation.Span.End); if (invocation.ContainsDirectives(span)) { return; } context.ReportDiagnostic( DiagnosticDescriptors.SimplifyLinqMethodChain, Location.Create(invocation.SyntaxTree, span)); }
public static void Analyze(SyntaxNodeAnalysisContext context, SimpleMemberInvocationExpressionInfo invocationInfo) { InvocationExpressionSyntax invocationExpression = invocationInfo.InvocationExpression; if (invocationExpression.IsParentKind(SyntaxKind.SimpleMemberAccessExpression)) { return; } SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; IMethodSymbol methodSymbol = semanticModel.GetReducedExtensionMethodInfo(invocationExpression, cancellationToken).Symbol; if (methodSymbol == null) { return; } if (!SymbolUtility.IsLinqExtensionOfIEnumerableOfTWithoutParameters(methodSymbol, "Any", semanticModel)) { return; } string propertyName = CSharpUtility.GetCountOrLengthPropertyName(invocationInfo.Expression, semanticModel, cancellationToken); if (propertyName == null) { return; } context.ReportDiagnostic( DiagnosticDescriptors.UseCountOrLengthPropertyInsteadOfAnyMethod, Location.Create(context.Node.SyntaxTree, TextSpan.FromBounds(invocationInfo.Name.SpanStart, invocationExpression.Span.End)), ImmutableDictionary.CreateRange(new KeyValuePair <string, string>[] { new KeyValuePair <string, string>("PropertyName", propertyName) }), propertyName); }
public static void Analyze(SyntaxNodeAnalysisContext context, SimpleMemberInvocationExpressionInfo invocationInfo) { InvocationExpressionSyntax invocationExpression = invocationInfo.InvocationExpression; SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; IMethodSymbol methodSymbol = semanticModel.GetReducedExtensionMethodInfo(invocationExpression, cancellationToken).Symbol; if (methodSymbol == null) { return; } if (!SymbolUtility.IsLinqExtensionOfIEnumerableOfTWithoutParameters(methodSymbol, "Count", semanticModel)) { return; } string propertyName = CSharpUtility.GetCountOrLengthPropertyName(invocationInfo.Expression, semanticModel, cancellationToken); if (propertyName != null) { context.ReportDiagnostic( DiagnosticDescriptors.UseCountOrLengthPropertyInsteadOfCountMethod, Location.Create(context.Node.SyntaxTree, TextSpan.FromBounds(invocationInfo.Name.SpanStart, invocationExpression.Span.End)), ImmutableDictionary.CreateRange(new KeyValuePair <string, string>[] { new KeyValuePair <string, string>("PropertyName", propertyName) }), propertyName); } else { SyntaxNode parent = invocationExpression.Parent; switch (parent.Kind()) { case SyntaxKind.EqualsExpression: case SyntaxKind.NotEqualsExpression: { var equalsExpression = (BinaryExpressionSyntax)parent; if (equalsExpression.Left == invocationExpression) { if (equalsExpression.Right.IsNumericLiteralExpression("0")) { context.ReportDiagnostic(DiagnosticDescriptors.CallAnyInsteadOfCount, parent); } } else if (equalsExpression.Left.IsNumericLiteralExpression("0")) { context.ReportDiagnostic(DiagnosticDescriptors.CallAnyInsteadOfCount, parent); } break; } case SyntaxKind.GreaterThanExpression: { var equalsExpression = (BinaryExpressionSyntax)parent; if (equalsExpression.Left == invocationExpression) { if (equalsExpression.Right.IsNumericLiteralExpression("0")) { context.ReportDiagnostic(DiagnosticDescriptors.CallAnyInsteadOfCount, parent); } else { context.ReportDiagnostic(DiagnosticDescriptors.CallSkipAndAnyInsteadOfCount, parent); } } else if (equalsExpression.Left.IsNumericLiteralExpression("1")) { context.ReportDiagnostic(DiagnosticDescriptors.CallAnyInsteadOfCount, parent); } else { context.ReportDiagnostic(DiagnosticDescriptors.CallSkipAndAnyInsteadOfCount, parent); } break; } case SyntaxKind.GreaterThanOrEqualExpression: { var equalsExpression = (BinaryExpressionSyntax)parent; if (equalsExpression.Left == invocationExpression) { if (equalsExpression.Right.IsNumericLiteralExpression("1")) { context.ReportDiagnostic(DiagnosticDescriptors.CallAnyInsteadOfCount, parent); } else { context.ReportDiagnostic(DiagnosticDescriptors.CallSkipAndAnyInsteadOfCount, parent); } } else if (equalsExpression.Left.IsNumericLiteralExpression("0")) { context.ReportDiagnostic(DiagnosticDescriptors.CallAnyInsteadOfCount, parent); } else { context.ReportDiagnostic(DiagnosticDescriptors.CallSkipAndAnyInsteadOfCount, parent); } break; } case SyntaxKind.LessThanExpression: { var equalsExpression = (BinaryExpressionSyntax)parent; if (equalsExpression.Left == invocationExpression) { if (equalsExpression.Right.IsNumericLiteralExpression("1")) { context.ReportDiagnostic(DiagnosticDescriptors.CallAnyInsteadOfCount, parent); } else { context.ReportDiagnostic(DiagnosticDescriptors.CallSkipAndAnyInsteadOfCount, parent); } } else if (equalsExpression.Left.IsNumericLiteralExpression("0")) { context.ReportDiagnostic(DiagnosticDescriptors.CallAnyInsteadOfCount, parent); } else { context.ReportDiagnostic(DiagnosticDescriptors.CallSkipAndAnyInsteadOfCount, parent); } break; } case SyntaxKind.LessThanOrEqualExpression: { var equalsExpression = (BinaryExpressionSyntax)parent; if (equalsExpression.Left == invocationExpression) { if (equalsExpression.Right.IsNumericLiteralExpression("0")) { context.ReportDiagnostic(DiagnosticDescriptors.CallAnyInsteadOfCount, parent); } else { context.ReportDiagnostic(DiagnosticDescriptors.CallSkipAndAnyInsteadOfCount, parent); } } else if (equalsExpression.Left.IsNumericLiteralExpression("1")) { context.ReportDiagnostic(DiagnosticDescriptors.CallAnyInsteadOfCount, parent); } else { context.ReportDiagnostic(DiagnosticDescriptors.CallSkipAndAnyInsteadOfCount, parent); } break; } } } }
private static void AnalyzeInvocationExpression(SyntaxNodeAnalysisContext context) { var invocationExpression = (InvocationExpressionSyntax)context.Node; if (invocationExpression.ContainsDiagnostics) { return; } SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocationExpression); if (!invocationInfo.Success) { return; } if (invocationInfo.Arguments.Count != 0) { return; } if (invocationInfo.NameText != "Count") { return; } SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; IMethodSymbol methodSymbol = semanticModel.GetReducedExtensionMethodInfo(invocationExpression, cancellationToken).Symbol; if (methodSymbol == null) { return; } if (!SymbolUtility.IsLinqExtensionOfIEnumerableOfTWithoutParameters(methodSymbol, "Count")) { return; } SyntaxNode parent = invocationExpression.Parent; switch (parent.Kind()) { case SyntaxKind.GreaterThanExpression: case SyntaxKind.LessThanOrEqualExpression: { var binaryExpression = (BinaryExpressionSyntax)parent; if (binaryExpression.Left == invocationExpression) { if (!binaryExpression.Right.IsNumericLiteralExpression("0")) { ReportDiagnostic(parent); } } else if (!binaryExpression.Left.IsNumericLiteralExpression("1")) { ReportDiagnostic(parent); } break; } case SyntaxKind.GreaterThanOrEqualExpression: case SyntaxKind.LessThanExpression: { var binaryExpression = (BinaryExpressionSyntax)parent; if (binaryExpression.Left == invocationExpression) { if (!binaryExpression.Right.IsNumericLiteralExpression("1")) { ReportDiagnostic(parent); } } else if (!binaryExpression.Left.IsNumericLiteralExpression("0")) { ReportDiagnostic(parent); } break; } } void ReportDiagnostic(SyntaxNode node) { context.ReportDiagnostic(DiagnosticDescriptors.CallSkipAndAnyInsteadOfCount, node); } }