| File: Microsoft.NetCore.Analyzers\Performance\CSharpPreferLengthCountIsEmptyOverAny.Fixer.cs | Web Access |
| Project: src\sdk\src\Microsoft.CodeAnalysis.NetAnalyzers\src\Microsoft.CodeAnalysis.CSharp.NetAnalyzers\Microsoft.CodeAnalysis.CSharp.NetAnalyzers.csproj (Microsoft.CodeAnalysis.CSharp.NetAnalyzers) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Composition; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.NetCore.Analyzers.Performance; using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; namespace Microsoft.NetCore.CSharp.Analyzers.Performance { [ExportCodeFixProvider(LanguageNames.CSharp), Shared] public sealed class CSharpPreferLengthCountIsEmptyOverAnyFixer : PreferLengthCountIsEmptyOverAnyFixer { protected override SyntaxNode? ReplaceAnyWithIsEmpty(SyntaxNode root, SyntaxNode node) { if (node is not InvocationExpressionSyntax { Expression: MemberAccessExpressionSyntax memberAccess } invocation) { return null; } var expression = memberAccess.Expression; if (invocation.ArgumentList.Arguments.Count > 0) { expression = invocation.ArgumentList.Arguments[0].Expression; } var newMemberAccess = MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, expression, IdentifierName(PreferLengthCountIsEmptyOverAnyAnalyzer.IsEmptyText) ); if (invocation.Parent.IsKind(SyntaxKind.LogicalNotExpression)) { return root.ReplaceNode(invocation.Parent, newMemberAccess.WithTriviaFrom(invocation.Parent)); } var negatedExpression = PrefixUnaryExpression( SyntaxKind.LogicalNotExpression, newMemberAccess ); return root.ReplaceNode(invocation, negatedExpression.WithTriviaFrom(invocation)); } protected override SyntaxNode? ReplaceAnyWithLength(SyntaxNode root, SyntaxNode node) { return ReplaceAnyWithPropertyCheck(root, node, PreferLengthCountIsEmptyOverAnyAnalyzer.LengthText); } protected override SyntaxNode? ReplaceAnyWithCount(SyntaxNode root, SyntaxNode node) { return ReplaceAnyWithPropertyCheck(root, node, PreferLengthCountIsEmptyOverAnyAnalyzer.CountText); } private static SyntaxNode? ReplaceAnyWithPropertyCheck(SyntaxNode root, SyntaxNode node, string propertyName) { if (node is not InvocationExpressionSyntax { Expression: MemberAccessExpressionSyntax memberAccess } invocation) { return null; } var expression = memberAccess.Expression; if (invocation.ArgumentList.Arguments.Count > 0) { // .Any() used like a normal static method and not like an extension method. expression = invocation.ArgumentList.Arguments[0].Expression; } static BinaryExpressionSyntax GetBinaryExpression(ExpressionSyntax expression, string member, SyntaxKind expressionKind) { return BinaryExpression( expressionKind, MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, expression, IdentifierName(member) ), LiteralExpression( SyntaxKind.NumericLiteralExpression, Literal(0) ) ); } if (invocation.Parent.IsKind(SyntaxKind.LogicalNotExpression)) { var binaryExpression = GetBinaryExpression(expression, propertyName, SyntaxKind.EqualsExpression); return root.ReplaceNode(invocation.Parent, binaryExpression.WithTriviaFrom(invocation.Parent)); } return root.ReplaceNode(invocation, GetBinaryExpression(expression, propertyName, SyntaxKind.NotEqualsExpression).WithTriviaFrom(invocation)); } } }