public static void Analyze(SyntaxNodeAnalysisContext context, SimpleMemberInvocationExpressionInfo invocationInfo) { ExpressionSyntax expression = invocationInfo.InvocationExpression.WalkUpParentheses(); SyntaxNode parent = expression.Parent; SyntaxKind kind = parent.Kind(); if (kind == SyntaxKind.SimpleMemberAccessExpression) { SimpleMemberInvocationExpressionInfo invocationInfo2 = SyntaxInfo.SimpleMemberInvocationExpressionInfo(parent.Parent); if (!invocationInfo2.Success) { return; } Analyze(context, invocationInfo, invocationInfo2); } else if (kind == SyntaxKind.Argument) { Analyze(context, invocationInfo, (ArgumentSyntax)parent); } else if (kind == SyntaxKind.EqualsExpression || kind == SyntaxKind.NotEqualsExpression) { Analyze(context, invocationInfo, expression, (BinaryExpressionSyntax)parent); } }
public static void Analyze(SyntaxNodeAnalysisContext context, SimpleMemberInvocationExpressionInfo invocationInfo) { ExpressionSyntax expression = invocationInfo.Expression; if (expression.Kind() != SyntaxKind.InvocationExpression) { return; } SimpleMemberInvocationExpressionInfo invocationInfo2 = SyntaxInfo.SimpleMemberInvocationExpressionInfo((InvocationExpressionSyntax)expression); if (!invocationInfo2.Success) { return; } if (!StringUtility.Equals(invocationInfo2.NameText, "OrderBy", "OrderByDescending")) { return; } if (IsOrderByOrOrderByDescending(invocationInfo.InvocationExpression, context.SemanticModel, context.CancellationToken) && IsOrderByOrOrderByDescending(invocationInfo2.InvocationExpression, context.SemanticModel, context.CancellationToken)) { context.ReportDiagnostic( DiagnosticDescriptors.CallThenByInsteadOfOrderBy, invocationInfo.Name, (invocationInfo.NameText == "OrderByDescending") ? "Descending" : null); } }
public override bool IsFixableStatement( StatementSyntax statement, string name, ITypeSymbol typeSymbol, SemanticModel semanticModel, CancellationToken cancellationToken) { if (statement.SpanOrLeadingTriviaContainsDirectives()) return false; if (!(statement is ExpressionStatementSyntax expressionStatement)) return false; SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(expressionStatement.Expression); if (!invocationInfo.Success) return false; if (!(WalkDownMethodChain(invocationInfo).Expression is IdentifierNameSyntax identifierName)) return false; if (name != identifierName.Identifier.ValueText) return false; IMethodSymbol methodSymbol = semanticModel.GetMethodSymbol(invocationInfo.InvocationExpression, cancellationToken); return methodSymbol?.IsStatic == false && SymbolEqualityComparer.Default.Equals(methodSymbol.ContainingType, typeSymbol) && SymbolEqualityComparer.Default.Equals(methodSymbol.ReturnType, typeSymbol); }
public static bool IsFixable( InvocationExpressionSyntax invocation, SemanticModel semanticModel, CancellationToken cancellationToken = default(CancellationToken)) { SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocation); if (!invocationInfo.Success) { return(false); } if (invocationInfo.Arguments.Count != 1) { return(false); } MemberAccessExpressionSyntax memberAccess = GetTopmostMemberAccessExpression(invocationInfo.MemberAccessExpression); if (invocationInfo.NameText != "HasFlag") { return(false); } IMethodSymbol methodSymbol = semanticModel.GetMethodSymbol(memberAccess, cancellationToken); return(methodSymbol?.Name == "HasFlag" && !methodSymbol.IsStatic && methodSymbol.IsReturnType(SpecialType.System_Boolean) && methodSymbol.HasSingleParameter(SpecialType.System_Enum) && methodSymbol.IsContainingType(SpecialType.System_Enum)); }
static string GetName2(InvocationExpressionSyntax invocationExpression) { SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocationExpression); if (!invocationInfo.Success) { return(null); } if (invocationInfo.Arguments.Any()) { return(null); } if (invocationInfo.NameText != "Kind") { return(null); } if (invocationInfo.Expression is not IdentifierNameSyntax identifierName) { return(null); } return(identifierName.Identifier.ValueText); }
private static bool VerifyAwaitType(AwaitExpressionSyntax awaitExpression, ITypeSymbol typeArgument, SemanticModel semanticModel, CancellationToken cancellationToken) { if (!typeArgument.Equals(semanticModel.GetTypeSymbol(awaitExpression, cancellationToken))) { return(false); } ExpressionSyntax expression = awaitExpression.Expression; ITypeSymbol expressionTypeSymbol = semanticModel.GetTypeSymbol(expression, cancellationToken); if (expressionTypeSymbol == null) { return(false); } if (expressionTypeSymbol.OriginalDefinition.EqualsOrInheritsFrom(MetadataNames.System_Threading_Tasks_Task_T)) { return(true); } SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(expression); return(invocationInfo.Success && invocationInfo.Arguments.Count == 1 && invocationInfo.NameText == "ConfigureAwait" && expressionTypeSymbol.OriginalDefinition.HasMetadataName(MetadataNames.System_Runtime_CompilerServices_ConfiguredTaskAwaitable_T)); }
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)); }
private static void Analyze( SyntaxNodeAnalysisContext context, SimpleMemberInvocationExpressionInfo invocationInfo, ArgumentSyntax argument) { if (!(argument.Parent is ArgumentListSyntax argumentList)) { return; } SeparatedSyntaxList <ArgumentSyntax> arguments = argumentList.Arguments; if (arguments.Count != 2) { return; } SimpleMemberInvocationExpressionInfo equalsInvocation = SyntaxInfo.SimpleMemberInvocationExpressionInfo(argumentList.Parent); if (!equalsInvocation.Success) { return; } if (equalsInvocation.NameText != "Equals") { return; } if (!IsFixable(context, invocationInfo, argument, arguments)) { return; } IMethodSymbol methodSymbol = context.SemanticModel.GetMethodSymbol(equalsInvocation.InvocationExpression, context.CancellationToken); if (!SymbolUtility.IsPublicStaticNonGeneric(methodSymbol, "Equals")) { return; } if (!methodSymbol.IsContainingType(SpecialType.System_String)) { return; } if (!methodSymbol.IsReturnType(SpecialType.System_Boolean)) { return; } if (!methodSymbol.HasTwoParameters(SpecialType.System_String, SpecialType.System_String)) { return; } ReportDiagnostic(context, equalsInvocation); }
private static bool IsFixable(InvocationExpressionSyntax invocationExpression, SemanticModel semanticModel, CancellationToken cancellationToken) { SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocationExpression); if (!invocationInfo.Success) { return(false); } IMethodSymbol methodSymbol = semanticModel.GetMethodSymbol(invocationInfo.InvocationExpression, cancellationToken); if (methodSymbol == null) { return(false); } if (!methodSymbol.IsContainingType(SpecialType.System_String)) { return(false); } if (!methodSymbol.IsReturnType(SpecialType.System_String)) { return(false); } switch (methodSymbol.Name) { case "Substring": { if (methodSymbol.HasTwoParameters(SpecialType.System_Int32, SpecialType.System_Int32)) { return(true); } break; } case "Remove": { if (methodSymbol.HasSingleParameter(SpecialType.System_Int32)) { return(true); } break; } case "Format": { return(true); } } return(false); }
private static string GetTextToAppend(ExpressionStatementSyntax expressionStatement) { SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(GetInvocationExpression(expressionStatement)); SimpleMemberInvocationExpressionInfo firstMemberInvocation = UseMethodChainingAnalysis.WalkDownMethodChain(invocationInfo); InvocationExpressionSyntax invocationExpression = invocationInfo.InvocationExpression; return(invocationExpression .ToString() .Substring(firstMemberInvocation.OperatorToken.SpanStart - invocationExpression.SpanStart)); }
public static async Task <Document> RefactorAsync( Document document, InvocationExpressionSyntax invocationExpression, CancellationToken cancellationToken) { SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); MemberDeclarationSyntax memberDeclaration = invocationExpression.FirstAncestor <MemberDeclarationSyntax>(); Debug.Assert(memberDeclaration != null, ""); if (memberDeclaration != null) { TypeDeclarationSyntax typeDeclaration = memberDeclaration.FirstAncestor <TypeDeclarationSyntax>(); Debug.Assert(typeDeclaration != null, ""); if (typeDeclaration != null) { SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocationExpression); string fieldName = NameGenerator.Default.EnsureUniqueLocalName("_regex", semanticModel, invocationExpression.SpanStart, cancellationToken: cancellationToken); MemberAccessExpressionSyntax newMemberAccess = invocationInfo.MemberAccessExpression.WithExpression(IdentifierName(Identifier(fieldName).WithRenameAnnotation())); ArgumentListPair pair = RewriteArgumentLists(invocationInfo.ArgumentList, semanticModel, cancellationToken); InvocationExpressionSyntax newInvocationExpression = invocationExpression .WithExpression(newMemberAccess) .WithArgumentList(pair.ArgumentList1); TypeDeclarationSyntax newTypeDeclaration = typeDeclaration.ReplaceNode(invocationExpression, newInvocationExpression); TypeSyntax regexType = ParseTypeName("System.Text.RegularExpressions.Regex").WithSimplifierAnnotation(); FieldDeclarationSyntax fieldDeclaration = FieldDeclaration( Modifiers.Private_Static_ReadOnly(), regexType, Identifier(fieldName), EqualsValueClause( ObjectCreationExpression(regexType, pair.ArgumentList2))); SyntaxList <MemberDeclarationSyntax> newMembers = MemberDeclarationInserter.Default.Insert(newTypeDeclaration.Members, fieldDeclaration); newTypeDeclaration = newTypeDeclaration.WithMembers(newMembers); return(await document.ReplaceNodeAsync(typeDeclaration, newTypeDeclaration, cancellationToken).ConfigureAwait(false)); } } return(document); }
public static bool IsFixable( InvocationExpressionSyntax invocation, SemanticModel semanticModel, CancellationToken cancellationToken = default(CancellationToken)) { if (!ParentIsElementAccessOrForEachExpression(invocation.WalkUpParentheses())) { return(false); } SimpleMemberInvocationExpressionInfo info = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocation); if (!info.Success) { return(false); } if (info.Arguments.Any()) { return(false); } if (!string.Equals(info.NameText, "ToCharArray")) { return(false); } IMethodSymbol methodSymbol = semanticModel.GetMethodSymbol(invocation, cancellationToken); if (!SymbolUtility.IsPublicInstanceNonGeneric(methodSymbol, "ToCharArray")) { return(false); } if (methodSymbol.ContainingType?.SpecialType != SpecialType.System_String) { return(false); } if (methodSymbol.Parameters.Any()) { return(false); } if (!(methodSymbol.ReturnType is IArrayTypeSymbol arrayType)) { return(false); } return(arrayType.ElementType.SpecialType == SpecialType.System_Char); }
private static Task <Document> AddCallToConfigureAwaitRefactorAsync( Document document, AwaitExpressionSyntax awaitExpression, CancellationToken cancellationToken) { ExpressionSyntax expression = awaitExpression.Expression; SyntaxTriviaList leading = default; switch (expression.Kind()) { case SyntaxKind.SimpleMemberAccessExpression: { var memberAccess = (MemberAccessExpressionSyntax)expression; leading = memberAccess.OperatorToken.LeadingTrivia; break; } case SyntaxKind.InvocationExpression: { var invocation = (InvocationExpressionSyntax)expression; SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocation); leading = invocationInfo.OperatorToken.LeadingTrivia; break; } } SyntaxTrivia last = leading.LastOrDefault(); last = (last.IsWhitespaceTrivia()) ? last : default; ParenthesizedExpressionSyntax expression2 = expression.WithoutTrailingTrivia().Parenthesize(); if (last.IsWhitespaceTrivia()) { expression2 = expression2.WithTrailingTrivia(SyntaxTriviaAnalysis.DetermineEndOfLine(awaitExpression)); } InvocationExpressionSyntax newInvocationExpression = InvocationExpression( SimpleMemberAccessExpression( expression2, Token(SyntaxKind.DotToken).WithLeadingTrivia(last), IdentifierName("ConfigureAwait")), ArgumentList( Token(SyntaxKind.OpenParenToken), SingletonSeparatedList(Argument(FalseLiteralExpression())), Token(default, SyntaxKind.CloseParenToken, expression.GetTrailingTrivia())));
public static SimpleMemberInvocationExpressionInfo WalkDownMethodChain(SimpleMemberInvocationExpressionInfo invocationInfo) { while (true) { SimpleMemberInvocationExpressionInfo invocationInfo2 = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocationInfo.Expression); if (invocationInfo2.Success) { invocationInfo = invocationInfo2; } else { break; } } return(invocationInfo); }
private static bool TryCreateCaseChangingInvocation(ExpressionSyntax expression, out SimpleMemberInvocationExpressionInfo invocationInfo) { invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(expression); if (invocationInfo.Success && !invocationInfo.Arguments.Any()) { string name = invocationInfo.NameText; return(name == "ToLower" || name == "ToLowerInvariant" || name == "ToUpper" || name == "ToUpperInvariant"); } invocationInfo = default(SimpleMemberInvocationExpressionInfo); return(false); }
public static Task <Document> RefactorAsync( Document document, SimpleMemberInvocationExpressionInfo invocationInfo, CancellationToken cancellationToken) { SimpleMemberInvocationExpressionInfo invocationInfo2 = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocationInfo.Expression); SyntaxTriviaList trivia = invocationInfo2.InvocationExpression .GetTrailingTrivia() .EmptyIfWhitespace() .AddRange(invocationInfo.InvocationExpression.GetTrailingTrivia()); InvocationExpressionSyntax newNode = invocationInfo2 .WithName("AppendLine") .InvocationExpression .WithTrailingTrivia(trivia); return(document.ReplaceNodeAsync(invocationInfo.InvocationExpression, newNode, cancellationToken)); }
private static InvocationExpressionSyntax CreateInvocationExpression( InvocationExpressionSyntax innerInvocationExpression, InvocationExpressionSyntax outerInvocationExpression) { SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(innerInvocationExpression); switch (invocationInfo.NameText) { case "Substring": { SeparatedSyntaxList <ArgumentSyntax> arguments = invocationInfo.Arguments; ArgumentListSyntax argumentList = ArgumentList( Argument(invocationInfo.Expression), arguments[0], arguments[1] ); return(CreateNewInvocationExpression(outerInvocationExpression, "Append", argumentList)); } case "Remove": { SeparatedSyntaxList <ArgumentSyntax> arguments = invocationInfo.Arguments; ArgumentListSyntax argumentList = ArgumentList( Argument(invocationInfo.Expression), Argument(NumericLiteralExpression(0)), arguments[0] ); return(CreateNewInvocationExpression(outerInvocationExpression, "Append", argumentList)); } case "Format": { return(CreateNewInvocationExpression(outerInvocationExpression, "AppendFormat", invocationInfo.ArgumentList)); } } Debug.Fail(innerInvocationExpression.ToString()); return(outerInvocationExpression); }
private static void AnalyzeInvocationExpression(SyntaxNodeAnalysisContext context) { var invocation = (InvocationExpressionSyntax)context.Node; if (invocation.ContainsDiagnostics) { return; } if (invocation.SpanContainsDirectives()) { return; } SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocation); if (invocationInfo.Arguments.Count != 1) { return; } if (!invocationInfo.Name.IsKind(SyntaxKind.IdentifierName)) { return; } if (invocationInfo.NameText != "HasFlag") { return; } if (!IsFixable(invocationInfo, context.SemanticModel, context.CancellationToken)) { return; } DiagnosticHelpers.ReportDiagnostic( context, DiagnosticRules.UseHasFlagMethodOrBitwiseOperator, invocation, "bitwise operator"); }
private static void RemoveCallToConfigureAwait(SyntaxNodeAnalysisContext context) { var awaitExpression = (AwaitExpressionSyntax)context.Node; ExpressionSyntax expression = awaitExpression.Expression; SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(expression); if (!IsConfigureAwait(expression)) { return; } ITypeSymbol typeSymbol = context.SemanticModel.GetTypeSymbol(expression, context.CancellationToken); if (typeSymbol == null) { return; } switch (typeSymbol.MetadataName) { case "ConfiguredTaskAwaitable": case "ConfiguredTaskAwaitable`1": case "ConfiguredValueTaskAwaitable": case "ConfiguredValueTaskAwaitable`1": { if (typeSymbol.ContainingNamespace.HasMetadataName(MetadataNames.System_Runtime_CompilerServices)) { DiagnosticHelpers.ReportDiagnostic( context, DiagnosticRules.ReportOnly.RemoveCallToConfigureAwait, Location.Create( awaitExpression.SyntaxTree, TextSpan.FromBounds(invocationInfo.OperatorToken.SpanStart, expression.Span.End)), AnalyzerOptions.RemoveCallToConfigureAwait); } break; } } }
private static Task <Document> UseElementAccessInsteadOfCallingFirstAsync( Document document, InvocationExpressionSyntax invocationExpression, CancellationToken cancellationToken) { SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocationExpression); ArgumentListSyntax argumentList = invocationInfo.ArgumentList; SyntaxToken openParenToken = argumentList.OpenParenToken; SyntaxToken closeParenToken = argumentList.CloseParenToken; ElementAccessExpressionSyntax elementAccessExpression = ElementAccessExpression( invocationInfo.Expression.WithoutTrailingTrivia(), BracketedArgumentList( Token(SyntaxTriviaList.Empty, SyntaxKind.OpenBracketToken, openParenToken.TrailingTrivia), SingletonSeparatedList(argumentList.Arguments.FirstOrDefault() ?? Argument(NumericLiteralExpression(0))), Token(closeParenToken.LeadingTrivia, SyntaxKind.CloseBracketToken, closeParenToken.TrailingTrivia))); return(document.ReplaceNodeAsync(invocationExpression, elementAccessExpression, cancellationToken)); }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false); if (!TryFindFirstAncestorOrSelf( root, context.Span, out SyntaxNode node, getInnermostNodeForTie: false, predicate: f => f.IsKind(SyntaxKind.Argument, SyntaxKind.InvocationExpression))) { return; } Diagnostic diagnostic = context.Diagnostics[0]; Document document = context.Document; if (node is ArgumentSyntax argument) { SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo((InvocationExpressionSyntax)argument.Parent.Parent); CodeAction codeAction = CodeAction.Create( $"Optimize '{invocationInfo.NameText}' call", ct => RefactorAsync(document, argument, invocationInfo, ct), GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); } else if (node is InvocationExpressionSyntax invocationExpression) { SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocationExpression); CodeAction codeAction = CodeAction.Create( $"Optimize '{invocationInfo.NameText}' call", ct => RefactorAsync(document, invocationInfo, ct), GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); } }
internal static async Task <Document> RefactorAsync( Document document, InvocationExpressionSyntax invocation, CancellationToken cancellationToken) { SimpleMemberInvocationExpressionInfo info = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocation); SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(info.Expression, cancellationToken); if ((typeSymbol as IArrayTypeSymbol)?.Rank == 1) { NameSyntax arrayName = ParseName("System.Array") .WithLeadingTrivia(invocation.GetLeadingTrivia()) .WithSimplifierAnnotation(); MemberAccessExpressionSyntax newMemberAccess = SimpleMemberAccessExpression( arrayName, info.OperatorToken, IdentifierName("Find").WithTriviaFrom(info.Name)); ArgumentListSyntax argumentList = invocation.ArgumentList; InvocationExpressionSyntax newInvocation = InvocationExpression( newMemberAccess, ArgumentList( Argument(info.Expression.WithoutTrivia()), argumentList.Arguments.First() ).WithTriviaFrom(argumentList)); return(await document.ReplaceNodeAsync(invocation, newInvocation, cancellationToken).ConfigureAwait(false)); } else { IdentifierNameSyntax newName = IdentifierName("Find").WithTriviaFrom(info.Name); return(await document.ReplaceNodeAsync(info.Name, newName, cancellationToken).ConfigureAwait(false)); } }
private bool IsCompletedTask(ExpressionSyntax expression) { if (expression.IsKind(SyntaxKind.SimpleMemberAccessExpression)) { var simpleMemberAccess = (MemberAccessExpressionSyntax)expression; return(string.Equals(simpleMemberAccess.Name.Identifier.ValueText, "CompletedTask", StringComparison.Ordinal) && SemanticModel.GetSymbol(expression, CancellationToken) is IPropertySymbol propertySymbol && IsTaskOrTaskOrT(propertySymbol.ContainingType)); } else { SimpleMemberInvocationExpressionInfo memberInvocation = SyntaxInfo.SimpleMemberInvocationExpressionInfo(expression); if (memberInvocation.Success) { switch (memberInvocation.NameText) { case "FromCanceled": case "FromException": case "FromResult": { if (SemanticModel.GetSymbol(expression, CancellationToken) is IMethodSymbol methodSymbol && (methodSymbol.Arity == 0 || methodSymbol.Arity == 1) && methodSymbol.Parameters.Length == 1 && IsTaskOrTaskOrT(methodSymbol.ContainingType)) { return(true); } break; } } } } return(false); }
private static async Task <Document> RefactorAsync( Document document, UsingStatementSyntax usingStatement, CancellationToken cancellationToken) { VariableDeclaratorSyntax declarator = usingStatement.Declaration.Variables.Single(); var whileStatement = (WhileStatementSyntax)usingStatement.Statement.SingleNonBlockStatementOrDefault(); SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(declarator.Initializer.Value); SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); string name = NameGenerator.Default.EnsureUniqueLocalName(DefaultNames.ForEachVariable, semanticModel, usingStatement.SpanStart, cancellationToken: cancellationToken); StatementSyntax statement = whileStatement.Statement; var rewriter = new Rewriter( semanticModel.GetDeclaredSymbol(declarator, cancellationToken), declarator.Identifier.ValueText, name, semanticModel, cancellationToken); var newStatement = (StatementSyntax)rewriter.Visit(statement); ForEachStatementSyntax forEachStatement = ForEachStatement( VarType(), Identifier(name).WithRenameAnnotation(), invocationInfo.Expression, newStatement); forEachStatement = forEachStatement .WithTriviaFrom(usingStatement) .WithFormatterAnnotation(); return(await document.ReplaceNodeAsync(usingStatement, forEachStatement, cancellationToken).ConfigureAwait(false)); }
private static bool IsConfiguredTaskAwaitableOfT( ExpressionSyntax expression, INamedTypeSymbol expressionTypeSymbol, SemanticModel semanticModel) { SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(expression); if (!invocationInfo.Success) { return(false); } if (invocationInfo.Arguments.Count != 1) { return(false); } if (invocationInfo.NameText != "ConfigureAwait") { return(false); } return(expressionTypeSymbol.ConstructedFrom.Equals(semanticModel.GetTypeByMetadataName(MetadataNames.System_Runtime_CompilerServices_ConfiguredTaskAwaitable_T))); }
public static bool IsFixable( InvocationExpressionSyntax invocation, SemanticModel semanticModel, CancellationToken cancellationToken = default(CancellationToken)) { SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocation); if (!invocationInfo.Success) { return(false); } if (invocationInfo.Arguments.Count != 1) { return(false); } if (invocationInfo.NameText != "HasFlag") { return(false); } return(IsFixable(invocationInfo, semanticModel, cancellationToken)); }
private static void AnalyzeInvocationExpression(SyntaxNodeAnalysisContext context) { var invocation = (InvocationExpressionSyntax)context.Node; if (invocation.ContainsDiagnostics) { return; } SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocation); if (!invocationInfo.Success) { return; } string methodName = invocationInfo.NameText; int argumentCount = invocationInfo.Arguments.Count; switch (argumentCount) { case 0: { switch (methodName) { case "Any": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.UseCountOrLengthPropertyInsteadOfAnyMethod)) { UseCountOrLengthPropertyInsteadOfAnyMethodAnalysis.Analyze(context, invocationInfo); } if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.OptimizeLinqMethodCall)) { OptimizeLinqMethodCallAnalysis.AnalyzeWhere(context, invocationInfo); OptimizeLinqMethodCallAnalysis.AnalyzeAny(context, invocationInfo); } break; } case "Cast": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.OptimizeLinqMethodCall)) { OptimizeLinqMethodCallAnalysis.AnalyzeWhereAndCast(context, invocationInfo); } if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.RemoveRedundantCast)) { RemoveRedundantCastAnalyzer.Analyze(context, invocationInfo); } break; } case "Count": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.OptimizeLinqMethodCall) && !OptimizeLinqMethodCallAnalysis.AnalyzeSelectManyAndCount(context, invocationInfo)) { OptimizeLinqMethodCallAnalysis.AnalyzeCount(context, invocationInfo); OptimizeLinqMethodCallAnalysis.AnalyzeWhere(context, invocationInfo); } break; } case "First": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.OptimizeLinqMethodCall)) { if (CanUseElementAccess(context, invocationInfo) && UseElementAccessAnalysis.IsFixableFirst(invocationInfo, context.SemanticModel, context.CancellationToken)) { DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.UseElementAccess, Location.Create(invocation.SyntaxTree, TextSpan.FromBounds(invocationInfo.Name.SpanStart, invocationInfo.ArgumentList.Span.End))); } OptimizeLinqMethodCallAnalysis.AnalyzeWhere(context, invocationInfo); OptimizeLinqMethodCallAnalysis.AnalyzeFirst(context, invocationInfo); } break; } case "Max": case "Min": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.OptimizeLinqMethodCall)) { OptimizeLinqMethodCallAnalysis.AnalyzeSelectAndMinOrMax(context, invocationInfo); } break; } case "Reverse": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.OptimizeLinqMethodCall)) { OptimizeLinqMethodCallAnalysis.AnalyzeOrderByAndReverse(context, invocationInfo); } break; } case "ToString": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.RemoveRedundantToStringCall)) { RemoveRedundantToStringCallAnalysis.Analyze(context, invocationInfo); } if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.UseNameOfOperator) && ((CSharpCompilation)context.Compilation).LanguageVersion >= LanguageVersion.CSharp6) { UseNameOfOperatorAnalyzer.Analyze(context, invocationInfo); } break; } case "ToLower": case "ToLowerInvariant": case "ToUpper": case "ToUpperInvariant": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.UseStringComparison)) { UseStringComparisonAnalysis.Analyze(context, invocationInfo); } break; } case "FirstOrDefault": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.OptimizeLinqMethodCall)) { OptimizeLinqMethodCallAnalysis.AnalyzeWhere(context, invocationInfo); OptimizeLinqMethodCallAnalysis.AnalyzeFirstOrDefault(context, invocationInfo); } break; } case "Last": case "LastOrDefault": case "LongCount": case "Single": case "SingleOrDefault": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.OptimizeLinqMethodCall)) { OptimizeLinqMethodCallAnalysis.AnalyzeWhere(context, invocationInfo); } break; } case "OfType": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.OptimizeLinqMethodCall) && !invocation.SpanContainsDirectives()) { OptimizeLinqMethodCallAnalysis.AnalyzeOfType(context, invocationInfo); } break; } case "ToCharArray": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.RemoveRedundantStringToCharArrayCall)) { RemoveRedundantStringToCharArrayCallAnalysis.Analyze(context, invocationInfo); } break; } } break; } case 1: { switch (methodName) { case "All": case "Any": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.SimplifyLogicalNegation)) { SimplifyLogicalNegationAnalyzer.Analyze(context, invocationInfo); } if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.OptimizeLinqMethodCall) && !invocation.SpanContainsDirectives()) { OptimizeLinqMethodCallAnalysis.AnalyzeWhereAndAny(context, invocationInfo); } break; } case "ContainsKey": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.OptimizeMethodCall)) { OptimizeMethodCallAnalysis.OptimizeDictionaryContainsKey(context, invocationInfo); } break; } case "ElementAt": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.OptimizeLinqMethodCall) && CanUseElementAccess(context, invocationInfo) && UseElementAccessAnalysis.IsFixableElementAt(invocationInfo, context.SemanticModel, context.CancellationToken)) { DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.UseElementAccess, Location.Create(invocation.SyntaxTree, TextSpan.FromBounds(invocationInfo.Name.SpanStart, invocationInfo.ArgumentList.Span.End))); } break; } case "FirstOrDefault": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.OptimizeLinqMethodCall)) { OptimizeLinqMethodCallAnalysis.AnalyzeFirstOrDefault(context, invocationInfo); } break; } case "GetValueOrDefault": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.UseCoalesceExpression) && invocationInfo.Name.IsKind(SyntaxKind.IdentifierName) && !invocation.IsParentKind(SyntaxKind.InvocationExpression, SyntaxKind.SimpleMemberAccessExpression, SyntaxKind.ElementAccessExpression) && context.SemanticModel .GetMethodSymbol(invocationInfo.InvocationExpression, context.CancellationToken)? .ContainingType .OriginalDefinition .SpecialType == SpecialType.System_Nullable_T) { DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.UseCoalesceExpression, invocationInfo.Name); } break; } case "Where": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.CombineEnumerableWhereMethodChain)) { CombineEnumerableWhereMethodChainAnalysis.Analyze(context, invocationInfo); } break; } case "HasFlag": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.ConvertHasFlagCallToBitwiseOperationOrViceVersa) && context.IsAnalyzerSuppressed(AnalyzerOptions.ConvertBitwiseOperationToHasFlagCall) && !invocation.SpanContainsDirectives() && ConvertHasFlagCallToBitwiseOperationAnalysis.IsFixable(invocationInfo, context.SemanticModel, context.CancellationToken)) { DiagnosticHelpers.ReportDiagnostic( context, DiagnosticDescriptors.ConvertHasFlagCallToBitwiseOperationOrViceVersa, invocation); } break; } case "Select": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.OptimizeLinqMethodCall)) { CallCastInsteadOfSelectAnalysis.Analyze(context, invocationInfo); } break; } case "OrderBy": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.CallThenByInsteadOfOrderBy)) { CallThenByInsteadOfOrderByAnalysis.Analyze(context, invocationInfo); } break; } } break; } case 2: { switch (invocationInfo.NameText) { case "IsMatch": case "Match": case "Matches": case "Split": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.UseRegexInstanceInsteadOfStaticMethod) && !invocation.SpanContainsDirectives()) { UseRegexInstanceInsteadOfStaticMethodAnalysis.Analyze(context, invocationInfo); } break; } case "Select": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.OptimizeLinqMethodCall)) { CallCastInsteadOfSelectAnalysis.Analyze(context, invocationInfo); } break; } case "OrderBy": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.CallThenByInsteadOfOrderBy)) { CallThenByInsteadOfOrderByAnalysis.Analyze(context, invocationInfo); } break; } } break; } case 3: { switch (invocationInfo.NameText) { case "IsMatch": case "Match": case "Matches": case "Split": case "Replace": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.UseRegexInstanceInsteadOfStaticMethod) && !invocation.SpanContainsDirectives()) { UseRegexInstanceInsteadOfStaticMethodAnalysis.Analyze(context, invocationInfo); } break; } case "OrderBy": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.CallThenByInsteadOfOrderBy)) { CallThenByInsteadOfOrderByAnalysis.Analyze(context, invocationInfo); } break; } case "Compare": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.OptimizeMethodCall)) { OptimizeMethodCallAnalysis.OptimizeStringCompare(context, invocationInfo); } break; } } break; } case 4: { switch (invocationInfo.NameText) { case "Replace": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.UseRegexInstanceInsteadOfStaticMethod) && !invocation.SpanContainsDirectives()) { UseRegexInstanceInsteadOfStaticMethodAnalysis.Analyze(context, invocationInfo); } break; } } break; } } switch (methodName) { case "ElementAtOrDefault": case "FirstOrDefault": case "LastOrDefault": case "SingleOrDefault": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.AvoidNullReferenceException)) { if (argumentCount == 0 || argumentCount == 1 || argumentCount == 2) { AvoidNullReferenceExceptionAnalyzer.Analyze(context, invocationInfo); } } break; } case "Append": case "AppendLine": case "AppendFormat": case "Insert": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.OptimizeStringBuilderAppendCall)) { OptimizeStringBuilderAppendCallAnalysis.Analyze(context, invocationInfo); } if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.AvoidBoxingOfValueType)) { AvoidBoxingOfValueTypeAnalysis.Analyze(context, invocationInfo); } break; } case "Assert": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.OptimizeMethodCall) && (argumentCount >= 1 && argumentCount <= 3)) { OptimizeMethodCallAnalysis.OptimizeDebugAssert(context, invocationInfo); } break; } case "Join": { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.OptimizeMethodCall) && argumentCount >= 2) { OptimizeMethodCallAnalysis.OptimizeStringJoin(context, invocationInfo); } break; } } if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.UseMethodChaining) && UseMethodChainingAnalysis.IsFixable(invocationInfo, context.SemanticModel, context.CancellationToken)) { DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.UseMethodChaining, invocationInfo.InvocationExpression); } }
public static async Task <Document> RefactorAsync( Document document, UseMethodChainingAnalysis analysis, ExpressionStatementSyntax expressionStatement, CancellationToken cancellationToken) { SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); InvocationExpressionSyntax invocationExpression = GetInvocationExpression(expressionStatement); SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocationExpression); ITypeSymbol returnType = semanticModel.GetMethodSymbol(invocationExpression, cancellationToken).ReturnType; string name = ((IdentifierNameSyntax)UseMethodChainingAnalysis.WalkDownMethodChain(invocationInfo).Expression).Identifier.ValueText; StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(expressionStatement); SyntaxList <StatementSyntax> statements = statementsInfo.Statements; int index = statements.IndexOf(expressionStatement); string indentation = SyntaxTriviaAnalysis.GetIncreasedIndentation(expressionStatement, cancellationToken); var sb = new StringBuilder(invocationExpression.ToString()); int j = index; while (j < statements.Count - 1) { StatementSyntax statement = statements[j + 1]; if (!analysis.IsFixableStatement(statement, name, returnType, semanticModel, cancellationToken)) { break; } sb.AppendLine(); sb.Append(indentation); sb.Append(GetTextToAppend((ExpressionStatementSyntax)statement)); j++; } StatementSyntax lastStatement = statements[j]; SyntaxList <StatementSyntax> newStatements = statements; while (j > index) { newStatements = newStatements.RemoveAt(j); j--; } ExpressionSyntax newInvocationExpression = SyntaxFactory.ParseExpression(sb.ToString()); SyntaxTriviaList trailingTrivia = statementsInfo .Parent .DescendantTrivia(TextSpan.FromBounds(invocationExpression.Span.End, lastStatement.Span.End)) .ToSyntaxTriviaList() .EmptyIfWhitespace() .AddRange(lastStatement.GetTrailingTrivia()); ExpressionStatementSyntax newExpressionStatement = expressionStatement .ReplaceNode(invocationExpression, newInvocationExpression) .WithLeadingTrivia(expressionStatement.GetLeadingTrivia()) .WithTrailingTrivia(trailingTrivia) .WithFormatterAndSimplifierAnnotation(); newStatements = newStatements.ReplaceAt(index, newExpressionStatement); return(await document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken).ConfigureAwait(false)); }
private static Task <Document> UsePatternMatchingAsync( Document document, SwitchStatementSyntax switchStatement, CancellationToken cancellationToken) { SyntaxList <SwitchSectionSyntax> newSections = switchStatement.Sections.Select(section => { if (!(section.Labels.Single() is CaseSwitchLabelSyntax label)) { return(section); } SyntaxList <StatementSyntax> statements = section.Statements; StatementSyntax statement = statements[0]; if (statement is BlockSyntax block) { statement = block.Statements.FirstOrDefault(); } SingleLocalDeclarationStatementInfo localInfo = SyntaxInfo.SingleLocalDeclarationStatementInfo((LocalDeclarationStatementSyntax)statement); var castExpression = (CastExpressionSyntax)localInfo.Value; CasePatternSwitchLabelSyntax newLabel = CasePatternSwitchLabel( DeclarationPattern( castExpression.Type, SingleVariableDesignation(localInfo.Identifier)), label.ColonToken); SwitchSectionSyntax newSection = section.RemoveStatement(localInfo.Statement); newSection = newSection.WithLabels(newSection.Labels.ReplaceAt(0, newLabel)); return(newSection.WithFormatterAnnotation()); }) .ToSyntaxList(); ExpressionSyntax expression = switchStatement.Expression; ExpressionSyntax newExpression = expression; LocalDeclarationStatementSyntax localDeclaration = null; if (expression.IsKind(SyntaxKind.InvocationExpression)) { SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(expression); newExpression = invocationInfo.Expression; } else { localDeclaration = (LocalDeclarationStatementSyntax)switchStatement.PreviousStatement(); SingleLocalDeclarationStatementInfo localInfo = SyntaxInfo.SingleLocalDeclarationStatementInfo(localDeclaration); SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(localInfo.Value); newExpression = invocationInfo.Expression; } SwitchStatementSyntax newSwitchStatement = switchStatement .WithExpression(newExpression.WithTriviaFrom(expression)) .WithSections(newSections); if (localDeclaration != null) { StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(switchStatement); newSwitchStatement = newSwitchStatement.WithLeadingTrivia(localDeclaration.GetLeadingTrivia()); SyntaxList <StatementSyntax> newStatements = statementsInfo.Statements .Replace(switchStatement, newSwitchStatement) .RemoveAt(statementsInfo.IndexOf(localDeclaration)); return(document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken)); } else { return(document.ReplaceNodeAsync(switchStatement, newSwitchStatement, cancellationToken)); } }
private static void AnalyzeInvocationExpression(SyntaxNodeAnalysisContext context) { var invocation = (InvocationExpressionSyntax)context.Node; if (UseBitwiseOperationInsteadOfCallingHasFlagAnalysis.IsFixable(invocation, context.SemanticModel, context.CancellationToken) && !invocation.SpanContainsDirectives()) { context.ReportDiagnostic(DiagnosticDescriptors.UseBitwiseOperationInsteadOfCallingHasFlag, invocation); } RemoveRedundantStringToCharArrayCallAnalysis.Analyze(context, invocation); SimplifyLinqMethodChainAnalysis.AnalyzeWhereAndAny(context); if (!invocation.ContainsDiagnostics) { if (!invocation.SpanContainsDirectives()) { CallExtensionMethodAsInstanceMethodAnalysisResult analysis = CallExtensionMethodAsInstanceMethodAnalysis.Analyze(invocation, context.SemanticModel, allowAnyExpression: false, cancellationToken: context.CancellationToken); if (analysis.Success && context.SemanticModel .GetEnclosingNamedType(analysis.InvocationExpression.SpanStart, context.CancellationToken)? .Equals(analysis.MethodSymbol.ContainingType) == false) { context.ReportDiagnostic(DiagnosticDescriptors.CallExtensionMethodAsInstanceMethod, invocation); } } SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocation); if (invocationInfo.Success) { if (!invocation.SpanContainsDirectives()) { UseRegexInstanceInsteadOfStaticMethodAnalysis.Analyze(context, invocationInfo); } string methodName = invocationInfo.NameText; AvoidNullReferenceExceptionAnalyzer.Analyze(context, invocationInfo); CallStringConcatInsteadOfStringJoinAnalysis.Analyze(context, invocationInfo); int argumentCount = invocationInfo.Arguments.Count; switch (argumentCount) { case 0: { switch (methodName) { case "Any": { UseCountOrLengthPropertyInsteadOfAnyMethodAnalysis.Analyze(context, invocationInfo); SimplifyLinqMethodChainAnalysis.AnalyzeWhere(context, invocationInfo); break; } case "Cast": { SimplifyLinqMethodChainAnalysis.AnalyzeWhereAndCast(context, invocationInfo); RemoveRedundantCastAnalyzer.Analyze(context, invocationInfo); break; } case "Count": { UseInsteadOfCountMethodAnalysis.Analyze(context, invocationInfo); SimplifyLinqMethodChainAnalysis.AnalyzeWhere(context, invocationInfo); break; } case "First": { if (!invocationInfo.Expression.IsKind(SyntaxKind.InvocationExpression) && UseElementAccessInsteadOfFirstAnalysis.IsFixable(invocationInfo, context.SemanticModel, context.CancellationToken)) { context.ReportDiagnostic(DiagnosticDescriptors.UseElementAccessInsteadOfFirst, invocationInfo.Name); } SimplifyLinqMethodChainAnalysis.AnalyzeWhere(context, invocationInfo); break; } case "ToString": { RemoveRedundantToStringCallAnalysis.Analyze(context, invocationInfo); UseNameOfOperatorAnalyzer.Analyze(context, invocationInfo); break; } case "ToLower": case "ToLowerInvariant": case "ToUpper": case "ToUpperInvariant": { UseStringComparisonAnalysis.Analyze(context, invocationInfo); break; } case "FirstOrDefault": case "Last": case "LastOrDefault": case "LongCount": case "Single": case "SingleOrDefault": { SimplifyLinqMethodChainAnalysis.AnalyzeWhere(context, invocationInfo); break; } } break; } case 1: { switch (methodName) { case "All": case "Any": { SimplifyLogicalNegationAnalyzer.Analyze(context, invocationInfo); break; } case "ElementAt": { if (!invocationInfo.Expression.IsKind(SyntaxKind.InvocationExpression) && UseElementAccessInsteadOfElementAtAnalysis.IsFixable(invocationInfo, context.SemanticModel, context.CancellationToken)) { context.ReportDiagnostic(DiagnosticDescriptors.UseElementAccessInsteadOfElementAt, invocationInfo.Name); } break; } case "FirstOrDefault": { SimplifyLinqMethodChainAnalysis.AnalyzeFirstOrDefault(context, invocationInfo); CallFindInsteadOfFirstOrDefaultAnalysis.Analyze(context, invocationInfo); break; } case "Where": { CombineEnumerableWhereMethodChainAnalysis.Analyze(context, invocationInfo); break; } } break; } } switch (methodName) { case "Append": case "AppendLine": case "AppendFormat": case "Insert": { OptimizeStringBuilderAppendCallAnalysis.Analyze(context, invocationInfo); break; } case "Select": { if (argumentCount == 1 || argumentCount == 2) { CallCastInsteadOfSelectAnalysis.Analyze(context, invocationInfo); } break; } case "OrderBy": case "OrderByDescending": { if (argumentCount == 1 || argumentCount == 2 || argumentCount == 3) { CallThenByInsteadOfOrderByAnalysis.Analyze(context, invocationInfo); } break; } } if (UseMethodChainingAnalysis.IsFixable(invocationInfo, context.SemanticModel, context.CancellationToken)) { context.ReportDiagnostic(DiagnosticDescriptors.UseMethodChaining, invocationInfo.InvocationExpression); } } } }