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 all 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,3 +4,4 @@

Rule ID | Category | Severity | Notes
--------|----------|----------|-------
CA1514 | Maintainability | Info | AvoidLengthCheckWhenSlicingToEndAnalyzer, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1514)
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.AvoidLengthCalculationWhenSlicingToEndTitle"/>
/// </summary>
[ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic), Shared]
public sealed class AvoidLengthCalculationWhenSlicingToEndFixer : CodeFixProvider
{
public sealed override ImmutableArray<string> FixableDiagnosticIds { get; } = ImmutableArray.Create(AvoidLengthCalculationWhenSlicingToEndAnalyzer.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.AvoidLengthCalculationWhenSlicingToEndCodeFixTitle,
ct => ReplaceWithStartOnlyCall(
context.Document,
invocationOperation.Instance.Syntax,
invocationOperation.TargetMethod.Name,
invocationOperation.Arguments.GetArgumentsInParameterOrder()[0],
ct),
nameof(MicrosoftCodeQualityAnalyzersResources.AvoidLengthCalculationWhenSlicingToEndCodeFixTitle));

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,18 @@
<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="AvoidLengthCalculationWhenSlicingToEndTitle" xml:space="preserve">
<value>Avoid redundant length argument</value>
</data>
<data name="AvoidLengthCalculationWhenSlicingToEndCodeFixTitle" xml:space="preserve">
<value>Remove redundant length argument</value>
</data>
<data name="AvoidLengthCalculationWhenSlicingToEndDescription" xml:space="preserve">
<value>An explicit length calculation can be error-prone and can be avoided when slicing to end of the buffer.</value>
</data>
<data name="AvoidLengthCalculationWhenSlicingToEndMessage" xml:space="preserve">
<value>'{0}' uses a redundant length calculation that can be removed</value>
</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,26 @@
<target state="translated">Zabránit nekonečné rekurzi</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndCodeFixTitle">
<source>Remove redundant length argument</source>
<target state="new">Remove redundant length argument</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndDescription">
<source>An explicit length calculation can be error-prone and can be avoided when slicing to end of the buffer.</source>
<target state="new">An explicit length calculation can be error-prone and can be avoided when slicing to end of the buffer.</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndMessage">
<source>'{0}' uses a redundant length calculation that can be removed</source>
<target state="new">'{0}' uses a redundant length calculation that can be removed</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndTitle">
<source>Avoid redundant length argument</source>
<target state="new">Avoid 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,26 @@
<target state="translated">Endlosrekursion vermeiden</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndCodeFixTitle">
<source>Remove redundant length argument</source>
<target state="new">Remove redundant length argument</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndDescription">
<source>An explicit length calculation can be error-prone and can be avoided when slicing to end of the buffer.</source>
<target state="new">An explicit length calculation can be error-prone and can be avoided when slicing to end of the buffer.</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndMessage">
<source>'{0}' uses a redundant length calculation that can be removed</source>
<target state="new">'{0}' uses a redundant length calculation that can be removed</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndTitle">
<source>Avoid redundant length argument</source>
<target state="new">Avoid 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,26 @@
<target state="translated">Evitar la recursividad infinita</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndCodeFixTitle">
<source>Remove redundant length argument</source>
<target state="new">Remove redundant length argument</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndDescription">
<source>An explicit length calculation can be error-prone and can be avoided when slicing to end of the buffer.</source>
<target state="new">An explicit length calculation can be error-prone and can be avoided when slicing to end of the buffer.</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndMessage">
<source>'{0}' uses a redundant length calculation that can be removed</source>
<target state="new">'{0}' uses a redundant length calculation that can be removed</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndTitle">
<source>Avoid redundant length argument</source>
<target state="new">Avoid 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,26 @@
<target state="translated">Éviter la récursivité infinie</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndCodeFixTitle">
<source>Remove redundant length argument</source>
<target state="new">Remove redundant length argument</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndDescription">
<source>An explicit length calculation can be error-prone and can be avoided when slicing to end of the buffer.</source>
<target state="new">An explicit length calculation can be error-prone and can be avoided when slicing to end of the buffer.</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndMessage">
<source>'{0}' uses a redundant length calculation that can be removed</source>
<target state="new">'{0}' uses a redundant length calculation that can be removed</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndTitle">
<source>Avoid redundant length argument</source>
<target state="new">Avoid 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,26 @@
<target state="translated">Evitare la ricorsione infinita</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndCodeFixTitle">
<source>Remove redundant length argument</source>
<target state="new">Remove redundant length argument</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndDescription">
<source>An explicit length calculation can be error-prone and can be avoided when slicing to end of the buffer.</source>
<target state="new">An explicit length calculation can be error-prone and can be avoided when slicing to end of the buffer.</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndMessage">
<source>'{0}' uses a redundant length calculation that can be removed</source>
<target state="new">'{0}' uses a redundant length calculation that can be removed</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndTitle">
<source>Avoid redundant length argument</source>
<target state="new">Avoid 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,26 @@
<target state="translated">無限再帰の回避</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndCodeFixTitle">
<source>Remove redundant length argument</source>
<target state="new">Remove redundant length argument</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndDescription">
<source>An explicit length calculation can be error-prone and can be avoided when slicing to end of the buffer.</source>
<target state="new">An explicit length calculation can be error-prone and can be avoided when slicing to end of the buffer.</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndMessage">
<source>'{0}' uses a redundant length calculation that can be removed</source>
<target state="new">'{0}' uses a redundant length calculation that can be removed</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndTitle">
<source>Avoid redundant length argument</source>
<target state="new">Avoid 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,26 @@
<target state="translated">무한 재귀 방지</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndCodeFixTitle">
<source>Remove redundant length argument</source>
<target state="new">Remove redundant length argument</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndDescription">
<source>An explicit length calculation can be error-prone and can be avoided when slicing to end of the buffer.</source>
<target state="new">An explicit length calculation can be error-prone and can be avoided when slicing to end of the buffer.</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndMessage">
<source>'{0}' uses a redundant length calculation that can be removed</source>
<target state="new">'{0}' uses a redundant length calculation that can be removed</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndTitle">
<source>Avoid redundant length argument</source>
<target state="new">Avoid 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,26 @@
<target state="translated">Unikaj nieskończonej rekursji</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndCodeFixTitle">
<source>Remove redundant length argument</source>
<target state="new">Remove redundant length argument</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndDescription">
<source>An explicit length calculation can be error-prone and can be avoided when slicing to end of the buffer.</source>
<target state="new">An explicit length calculation can be error-prone and can be avoided when slicing to end of the buffer.</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndMessage">
<source>'{0}' uses a redundant length calculation that can be removed</source>
<target state="new">'{0}' uses a redundant length calculation that can be removed</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndTitle">
<source>Avoid redundant length argument</source>
<target state="new">Avoid 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,26 @@
<target state="translated">Evitar a recursão infinita</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndCodeFixTitle">
<source>Remove redundant length argument</source>
<target state="new">Remove redundant length argument</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndDescription">
<source>An explicit length calculation can be error-prone and can be avoided when slicing to end of the buffer.</source>
<target state="new">An explicit length calculation can be error-prone and can be avoided when slicing to end of the buffer.</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndMessage">
<source>'{0}' uses a redundant length calculation that can be removed</source>
<target state="new">'{0}' uses a redundant length calculation that can be removed</target>
<note />
</trans-unit>
<trans-unit id="AvoidLengthCalculationWhenSlicingToEndTitle">
<source>Avoid redundant length argument</source>
<target state="new">Avoid 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
Loading
Loading