Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CA1514: Remove redundant length argument #6814

Merged
merged 7 commits into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

Rule ID | Category | Severity | Notes
--------|----------|----------|-------
CA1514 | Maintainability | Info | AvoidLengthCheckWhenSlicingToEndAnalyzer, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1514)
CA1865 | Performance | Info | UseStringMethodCharOverloadWithSingleCharacters, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1865)
CA1866 | Performance | Info | UseStringMethodCharOverloadWithSingleCharacters, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1866)
CA1867 | Performance | Disabled | UseStringMethodCharOverloadWithSingleCharacters, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1867)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information.

using System.Collections.Immutable;
using System.Composition;
using System.Threading;
using System.Threading.Tasks;
using Analyzer.Utilities;
using Analyzer.Utilities.Extensions;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.Editing;
using Microsoft.CodeAnalysis.Operations;

namespace Microsoft.CodeQuality.Analyzers.Maintainability
{
/// <summary>
/// CA1514: <inheritdoc cref="MicrosoftCodeQualityAnalyzersResources.@AvoidLengthCheckWhenSlicingToEndTitle"/>
mpidash marked this conversation as resolved.
Show resolved Hide resolved
/// </summary>
[ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic), Shared]
public sealed class AvoidLengthCheckWhenSlicingToEndFixer : CodeFixProvider
{
public sealed override ImmutableArray<string> FixableDiagnosticIds { get; } = ImmutableArray.Create(AvoidLengthCheckWhenSlicingToEndAnalyzer.RuleId);

public sealed override FixAllProvider GetFixAllProvider()
{
return WellKnownFixAllProviders.BatchFixer;
}

public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
{
var root = await context.Document.GetRequiredSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
var node = root.FindNode(context.Span, getInnermostNodeForTie: true);

if (node is null)
{
return;
}

var semanticModel = await context.Document.GetRequiredSemanticModelAsync(context.CancellationToken).ConfigureAwait(false);
var operation = semanticModel.GetOperation(node, context.CancellationToken);

if (operation is not IInvocationOperation invocationOperation ||
invocationOperation.Instance is null ||
invocationOperation.Arguments.Length != 2)
{
return;
}

var codeAction = CodeAction.Create(
MicrosoftCodeQualityAnalyzersResources.AvoidLengthCheckWhenSlicingToEndTitle,
ct => ReplaceWithStartOnlyCall(
context.Document,
invocationOperation.Instance.Syntax,
invocationOperation.TargetMethod.Name,
invocationOperation.Arguments.GetArgumentsInParameterOrder()[0],
ct),
nameof(MicrosoftCodeQualityAnalyzersResources.AvoidLengthCheckWhenSlicingToEndTitle));

context.RegisterCodeFix(codeAction, context.Diagnostics);

async Task<Document> ReplaceWithStartOnlyCall(
Document document,
SyntaxNode instance,
string methodName,
IArgumentOperation argument,
CancellationToken cancellationToken)
{
var editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false);
var generator = editor.Generator;
var methodExpression = generator.MemberAccessExpression(instance, methodName);
var methodInvocation = generator.InvocationExpression(methodExpression, argument.Syntax);

editor.ReplaceNode(invocationOperation.Syntax, methodInvocation.WithTriviaFrom(invocationOperation.Syntax));

return document.WithSyntaxRoot(editor.GetChangedRoot());
}
}
}
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,15 @@
<data name="DoNotIgnoreMethodResultsMessageTryParse" xml:space="preserve">
<value>{0} calls {1} but does not explicitly check whether the conversion succeeded. Either use the return value in a conditional statement or verify that the call site expects that the out argument will be set to the default value when the conversion fails.</value>
</data>
<data name="AvoidLengthCheckWhenSlicingToEndTitle" xml:space="preserve">
<value>Remove redundant length argument</value>
</data>
mpidash marked this conversation as resolved.
Show resolved Hide resolved
<data name="AvoidLengthCheckWhenSlicingToEndDescription" xml:space="preserve">
<value>An explicit length check can be error-prone and can be avoided when slicing to end of the buffer.</value>
</data>
<data name="AvoidLengthCheckWhenSlicingToEndMessage" xml:space="preserve">
<value>'{0}' uses a length check that can be avoided</value>
mpidash marked this conversation as resolved.
Show resolved Hide resolved
</data>
<data name="AvoidUninstantiatedInternalClassesTitle" xml:space="preserve">
<value>Avoid uninstantiated internal classes</value>
</data>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,21 @@
<target state="translated">Zabránit nekonečné rekurzi</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndDescription">
<source>An explicit length check can be error-prone and can be avoided when slicing to end of the buffer.</source>
<target state="new">An explicit length check can be error-prone and can be avoided when slicing to end of the buffer.</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndMessage">
<source>'{0}' uses a length check that can be avoided</source>
<target state="new">'{0}' uses a length check that can be avoided</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndTitle">
<source>Remove redundant length argument</source>
<target state="new">Remove redundant length argument</target>
<note />
</trans-unit>
<trans-unit id="AvoidMultipleEnumerationsMessage">
<source>Possible multiple enumerations of 'IEnumerable' collection. Consider using an implementation that avoids multiple enumerations.</source>
<target state="translated">Je možných více výčtů kolekce IEnumerable. Zvažte použití implementace, která zabraňuje více výčtům.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,21 @@
<target state="translated">Endlosrekursion vermeiden</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndDescription">
<source>An explicit length check can be error-prone and can be avoided when slicing to end of the buffer.</source>
<target state="new">An explicit length check can be error-prone and can be avoided when slicing to end of the buffer.</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndMessage">
<source>'{0}' uses a length check that can be avoided</source>
<target state="new">'{0}' uses a length check that can be avoided</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndTitle">
<source>Remove redundant length argument</source>
<target state="new">Remove redundant length argument</target>
<note />
</trans-unit>
<trans-unit id="AvoidMultipleEnumerationsMessage">
<source>Possible multiple enumerations of 'IEnumerable' collection. Consider using an implementation that avoids multiple enumerations.</source>
<target state="translated">Mögliche mehrere Enumerationen der IEnumerable-Auflistung. Erwägen Sie die Verwendung einer Implementierung, die mehrere Enumerationen vermeidet.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,21 @@
<target state="translated">Evitar la recursividad infinita</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndDescription">
<source>An explicit length check can be error-prone and can be avoided when slicing to end of the buffer.</source>
<target state="new">An explicit length check can be error-prone and can be avoided when slicing to end of the buffer.</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndMessage">
<source>'{0}' uses a length check that can be avoided</source>
<target state="new">'{0}' uses a length check that can be avoided</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndTitle">
<source>Remove redundant length argument</source>
<target state="new">Remove redundant length argument</target>
<note />
</trans-unit>
<trans-unit id="AvoidMultipleEnumerationsMessage">
<source>Possible multiple enumerations of 'IEnumerable' collection. Consider using an implementation that avoids multiple enumerations.</source>
<target state="translated">Posibles enumeraciones múltiples de la colección “IEnumerable”. Considere la posibilidad de usar una implementación que evite varias enumeraciones.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,21 @@
<target state="translated">Éviter la récursivité infinie</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndDescription">
<source>An explicit length check can be error-prone and can be avoided when slicing to end of the buffer.</source>
<target state="new">An explicit length check can be error-prone and can be avoided when slicing to end of the buffer.</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndMessage">
<source>'{0}' uses a length check that can be avoided</source>
<target state="new">'{0}' uses a length check that can be avoided</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndTitle">
<source>Remove redundant length argument</source>
<target state="new">Remove redundant length argument</target>
<note />
</trans-unit>
<trans-unit id="AvoidMultipleEnumerationsMessage">
<source>Possible multiple enumerations of 'IEnumerable' collection. Consider using an implementation that avoids multiple enumerations.</source>
<target state="translated">Possibilité d'énumérations multiples de la collection 'IEnumerable'. Envisagez d'utiliser une mise en œuvre qui évite les énumérations multiples.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,21 @@
<target state="translated">Evitare la ricorsione infinita</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndDescription">
<source>An explicit length check can be error-prone and can be avoided when slicing to end of the buffer.</source>
<target state="new">An explicit length check can be error-prone and can be avoided when slicing to end of the buffer.</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndMessage">
<source>'{0}' uses a length check that can be avoided</source>
<target state="new">'{0}' uses a length check that can be avoided</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndTitle">
<source>Remove redundant length argument</source>
<target state="new">Remove redundant length argument</target>
<note />
</trans-unit>
<trans-unit id="AvoidMultipleEnumerationsMessage">
<source>Possible multiple enumerations of 'IEnumerable' collection. Consider using an implementation that avoids multiple enumerations.</source>
<target state="translated">Possibili enumerazioni multiple della raccolta 'IEnumerable'. Considerare l'utilizzo di un'implementazione che eviti enumerazioni multiple.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,21 @@
<target state="translated">無限再帰の回避</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndDescription">
<source>An explicit length check can be error-prone and can be avoided when slicing to end of the buffer.</source>
<target state="new">An explicit length check can be error-prone and can be avoided when slicing to end of the buffer.</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndMessage">
<source>'{0}' uses a length check that can be avoided</source>
<target state="new">'{0}' uses a length check that can be avoided</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndTitle">
<source>Remove redundant length argument</source>
<target state="new">Remove redundant length argument</target>
<note />
</trans-unit>
<trans-unit id="AvoidMultipleEnumerationsMessage">
<source>Possible multiple enumerations of 'IEnumerable' collection. Consider using an implementation that avoids multiple enumerations.</source>
<target state="translated">'IEnumerable' コレクションを複数列挙している可能性があります。複数列挙を回避する実装を検討してください。</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,21 @@
<target state="translated">무한 재귀 방지</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndDescription">
<source>An explicit length check can be error-prone and can be avoided when slicing to end of the buffer.</source>
<target state="new">An explicit length check can be error-prone and can be avoided when slicing to end of the buffer.</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndMessage">
<source>'{0}' uses a length check that can be avoided</source>
<target state="new">'{0}' uses a length check that can be avoided</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndTitle">
<source>Remove redundant length argument</source>
<target state="new">Remove redundant length argument</target>
<note />
</trans-unit>
<trans-unit id="AvoidMultipleEnumerationsMessage">
<source>Possible multiple enumerations of 'IEnumerable' collection. Consider using an implementation that avoids multiple enumerations.</source>
<target state="translated">'IEnumerable' 컬렉션에 대해 여러 개의 열거형이 가능합니다. 여러 열거형을 방지하는 구현을 사용하는 것이 좋습니다.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,21 @@
<target state="translated">Unikaj nieskończonej rekursji</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndDescription">
<source>An explicit length check can be error-prone and can be avoided when slicing to end of the buffer.</source>
<target state="new">An explicit length check can be error-prone and can be avoided when slicing to end of the buffer.</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndMessage">
<source>'{0}' uses a length check that can be avoided</source>
<target state="new">'{0}' uses a length check that can be avoided</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndTitle">
<source>Remove redundant length argument</source>
<target state="new">Remove redundant length argument</target>
<note />
</trans-unit>
<trans-unit id="AvoidMultipleEnumerationsMessage">
<source>Possible multiple enumerations of 'IEnumerable' collection. Consider using an implementation that avoids multiple enumerations.</source>
<target state="translated">Możliwe wielokrotne wyliczenia kolekcji „IEnumerable”. Rozważ użycie implementacji, która pozwala uniknąć wielu wyliczeń.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,21 @@
<target state="translated">Evitar a recursão infinita</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndDescription">
<source>An explicit length check can be error-prone and can be avoided when slicing to end of the buffer.</source>
<target state="new">An explicit length check can be error-prone and can be avoided when slicing to end of the buffer.</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndMessage">
<source>'{0}' uses a length check that can be avoided</source>
<target state="new">'{0}' uses a length check that can be avoided</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndTitle">
<source>Remove redundant length argument</source>
<target state="new">Remove redundant length argument</target>
<note />
</trans-unit>
<trans-unit id="AvoidMultipleEnumerationsMessage">
<source>Possible multiple enumerations of 'IEnumerable' collection. Consider using an implementation that avoids multiple enumerations.</source>
<target state="translated">Possíveis várias enumerações da coleção 'IEnumerable'. Considere usar uma implementação que evite várias enumerações.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,21 @@
<target state="translated">Избегайте бесконечной рекурсии</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndDescription">
<source>An explicit length check can be error-prone and can be avoided when slicing to end of the buffer.</source>
<target state="new">An explicit length check can be error-prone and can be avoided when slicing to end of the buffer.</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndMessage">
<source>'{0}' uses a length check that can be avoided</source>
<target state="new">'{0}' uses a length check that can be avoided</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCheckWhenSlicingToEndTitle">
<source>Remove redundant length argument</source>
<target state="new">Remove redundant length argument</target>
<note />
</trans-unit>
<trans-unit id="AvoidMultipleEnumerationsMessage">
<source>Possible multiple enumerations of 'IEnumerable' collection. Consider using an implementation that avoids multiple enumerations.</source>
<target state="translated">Возможно несколько перечислений коллекции IEnumerable. Рассмотрите возможность использования реализации без нескольких перечислений.</target>
Expand Down
Loading