From 9d85cb0933bb993b7351cc3587263c73396bcfa7 Mon Sep 17 00:00:00 2001 From: David Barbet Date: Thu, 14 Dec 2023 14:31:31 -0800 Subject: [PATCH] Revert "Merge pull request #71258 from mavasani/RemoveFadingDiagnostics" This reverts commit dac459979942d53af078c91507d7118b332d841f, reversing changes made to 5249865bc562b64333ae80de6ccb47e7881b7840. --- ...keDelegateWithConditionalAccessAnalyzer.cs | 54 ++-- ...eCollectionExpressionDiagnosticAnalyzer.cs | 25 +- ...ionExpressionForArrayDiagnosticAnalyzer.cs | 23 +- ...nExpressionForBuilderDiagnosticAnalyzer.cs | 46 ++- ...onExpressionForCreateDiagnosticAnalyzer.cs | 26 +- ...pressionForStackAllocDiagnosticAnalyzer.cs | 46 +-- ...ateWithConditionalAccessCodeFixProvider.cs | 5 + ...ectionExpressionForEmptyCodeFixProvider.cs | 3 + .../UseThrowExpressionCodeFixProvider.cs | 3 + ...nvokeDelegateWithConditionalAccessTests.cs | 202 ++++++++++--- ...eWithConditionalAccessTests_FixAllTests.cs | 146 ++++++++- .../UseCollectionExpressionForArrayTests.cs | 190 ++++++------ .../UseCollectionExpressionForBuilderTests.cs | 96 +++--- .../UseCollectionExpressionForCreateTests.cs | 68 +++-- ...eCollectionExpressionForStackAllocTests.cs | 58 ++-- .../UseCollectionInitializerTests.cs | 70 ++--- ...onInitializerTests_CollectionExpression.cs | 278 +++++++++--------- ...CollectionInitializerDiagnosticAnalyzer.cs | 69 +++-- ...eTernaryConditionalCheckCodeFixProvider.cs | 3 + ...rTernaryConditionalCheckCodeFixProvider.cs | 3 + ...stractUseNullPropagationCodeFixProvider.cs | 3 + ...ForkingSyntaxEditorBasedCodeFixProvider.cs | 4 + 22 files changed, 891 insertions(+), 530 deletions(-) diff --git a/src/Analyzers/CSharp/Analyzers/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessAnalyzer.cs b/src/Analyzers/CSharp/Analyzers/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessAnalyzer.cs index 5d52246a68d3d..7269a32ae167a 100644 --- a/src/Analyzers/CSharp/Analyzers/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessAnalyzer.cs +++ b/src/Analyzers/CSharp/Analyzers/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessAnalyzer.cs @@ -10,7 +10,6 @@ using Microsoft.CodeAnalysis.CSharp.Extensions; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; @@ -24,13 +23,12 @@ internal static class Constants } [DiagnosticAnalyzer(LanguageNames.CSharp)] - internal class InvokeDelegateWithConditionalAccessAnalyzer : AbstractBuiltInUnnecessaryCodeStyleDiagnosticAnalyzer + internal class InvokeDelegateWithConditionalAccessAnalyzer : AbstractBuiltInCodeStyleDiagnosticAnalyzer { public InvokeDelegateWithConditionalAccessAnalyzer() : base(IDEDiagnosticIds.InvokeDelegateWithConditionalAccessId, EnforceOnBuildValues.InvokeDelegateWithConditionalAccess, CSharpCodeStyleOptions.PreferConditionalDelegateCall, - fadingOption: null, new LocalizableResourceString(nameof(CSharpAnalyzersResources.Delegate_invocation_can_be_simplified), CSharpAnalyzersResources.ResourceManager, typeof(CSharpAnalyzersResources))) { } @@ -172,40 +170,42 @@ private void ReportDiagnostics( ImmutableArray additionalLocations, string kind) { - var location = expressionStatement.GetLocation(); - var fadingLocations = GetLocationsToFade(); + var tree = syntaxContext.Node.SyntaxTree; + var properties = ImmutableDictionary.Empty.Add( Constants.Kind, kind); + var previousToken = expressionStatement.GetFirstToken().GetPreviousToken(); + var nextToken = expressionStatement.GetLastToken().GetNextToken(); + + // Fade out the code up to the expression statement. + var fadeLocation = Location.Create(tree, TextSpan.FromBounds(firstStatement.SpanStart, previousToken.Span.End)); syntaxContext.ReportDiagnostic(DiagnosticHelper.CreateWithLocationTags( Descriptor, - location, - notificationOption, + fadeLocation, + NotificationOption2.ForSeverity(Descriptor.DefaultSeverity), additionalLocations, - fadingLocations, + additionalUnnecessaryLocations: ImmutableArray.Create(fadeLocation), properties)); - return; + // Put a diagnostic with the appropriate severity on the expression-statement itself. + syntaxContext.ReportDiagnostic(DiagnosticHelper.Create( + Descriptor, + expressionStatement.GetLocation(), + notificationOption, + additionalLocations, properties)); - ImmutableArray GetLocationsToFade() + // If the if-statement extends past the expression statement, then fade out the rest. + if (nextToken.Span.Start < ifStatement.Span.End) { - var tree = syntaxContext.Node.SyntaxTree; - var previousToken = expressionStatement.GetFirstToken().GetPreviousToken(); - var nextToken = expressionStatement.GetLastToken().GetNextToken(); - - // Fade out the code up to the expression statement. - using var _ = ArrayBuilder.GetInstance(out var fadingLocations); - fadingLocations.Add( - Location.Create(tree, TextSpan.FromBounds(firstStatement.SpanStart, previousToken.Span.End))); - - // If the if-statement extends past the expression statement, then fade out the rest. - if (nextToken.Span.Start < ifStatement.Span.End) - { - fadingLocations.Add( - Location.Create(tree, TextSpan.FromBounds(nextToken.Span.Start, ifStatement.Span.End))); - } - - return fadingLocations.ToImmutable(); + fadeLocation = Location.Create(tree, TextSpan.FromBounds(nextToken.Span.Start, ifStatement.Span.End)); + syntaxContext.ReportDiagnostic(DiagnosticHelper.CreateWithLocationTags( + Descriptor, + fadeLocation, + NotificationOption2.ForSeverity(Descriptor.DefaultSeverity), + additionalLocations, + additionalUnnecessaryLocations: ImmutableArray.Create(fadeLocation), + properties)); } } diff --git a/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/AbstractCSharpUseCollectionExpressionDiagnosticAnalyzer.cs b/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/AbstractCSharpUseCollectionExpressionDiagnosticAnalyzer.cs index 2dc28a69e4de5..14d7286a729ae 100644 --- a/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/AbstractCSharpUseCollectionExpressionDiagnosticAnalyzer.cs +++ b/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/AbstractCSharpUseCollectionExpressionDiagnosticAnalyzer.cs @@ -16,16 +16,31 @@ namespace Microsoft.CodeAnalysis.CSharp.UseCollectionExpression; /// Base type for all analyzers that offer to update code to use a collection-expression. /// internal abstract class AbstractCSharpUseCollectionExpressionDiagnosticAnalyzer - : AbstractBuiltInUnnecessaryCodeStyleDiagnosticAnalyzer + : AbstractBuiltInCodeStyleDiagnosticAnalyzer { + protected new readonly DiagnosticDescriptor Descriptor; + protected readonly DiagnosticDescriptor UnnecessaryCodeDescriptor; + protected AbstractCSharpUseCollectionExpressionDiagnosticAnalyzer(string diagnosticId, EnforceOnBuild enforceOnBuild) - : base(diagnosticId, enforceOnBuild, CodeStyleOptions2.PreferCollectionExpression, - fadingOption: null, - title: new LocalizableResourceString(nameof(AnalyzersResources.Simplify_collection_initialization), AnalyzersResources.ResourceManager, typeof(AnalyzersResources)), - messageFormat: new LocalizableResourceString(nameof(AnalyzersResources.Collection_initialization_can_be_simplified), AnalyzersResources.ResourceManager, typeof(AnalyzersResources))) + : base(ImmutableDictionary.Empty + // Ugly hack. We need to create a descriptor to pass to our base *and* assign to one of our fields. + // The conditional pattern form lets us do that. + .Add(CreateDescriptor(diagnosticId, enforceOnBuild, isUnnecessary: false) is var descriptor ? descriptor : null, CodeStyleOptions2.PreferCollectionExpression) + .Add(CreateDescriptor(diagnosticId, enforceOnBuild, isUnnecessary: true) is var unnecessaryCodeDescriptor ? unnecessaryCodeDescriptor : null, CodeStyleOptions2.PreferCollectionExpression)) { + Descriptor = descriptor; + UnnecessaryCodeDescriptor = unnecessaryCodeDescriptor; } + private static DiagnosticDescriptor CreateDescriptor(string diagnosticId, EnforceOnBuild enforceOnBuild, bool isUnnecessary) + => CreateDescriptorWithId( + diagnosticId, + enforceOnBuild, + hasAnyCodeStyleOption: true, + new LocalizableResourceString(nameof(AnalyzersResources.Simplify_collection_initialization), AnalyzersResources.ResourceManager, typeof(AnalyzersResources)), + new LocalizableResourceString(nameof(AnalyzersResources.Collection_initialization_can_be_simplified), AnalyzersResources.ResourceManager, typeof(AnalyzersResources)), + isUnnecessary: isUnnecessary); + protected abstract void InitializeWorker(CodeBlockStartAnalysisContext context, INamedTypeSymbol? expressionType); protected virtual bool IsSupported(Compilation compilation) diff --git a/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/CSharpUseCollectionExpressionForArrayDiagnosticAnalyzer.cs b/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/CSharpUseCollectionExpressionForArrayDiagnosticAnalyzer.cs index 0dc5c3afb05e9..888682c4bde60 100644 --- a/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/CSharpUseCollectionExpressionForArrayDiagnosticAnalyzer.cs +++ b/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/CSharpUseCollectionExpressionForArrayDiagnosticAnalyzer.cs @@ -162,9 +162,15 @@ private void AnalyzeArrayInitializerExpression(SyntaxNodeAnalysisContext context private void ReportArrayCreationDiagnostics(SyntaxNodeAnalysisContext context, SyntaxTree syntaxTree, CodeStyleOption2 option, ExpressionSyntax expression) { - var location = expression.GetFirstToken().GetLocation(); - var additionalLocations = ImmutableArray.Create(expression.GetLocation()); - var fadingLocations = ImmutableArray.Create( + var locations = ImmutableArray.Create(expression.GetLocation()); + context.ReportDiagnostic(DiagnosticHelper.Create( + Descriptor, + expression.GetFirstToken().GetLocation(), + option.Notification, + additionalLocations: locations, + properties: null)); + + var additionalUnnecessaryLocations = ImmutableArray.Create( syntaxTree.GetLocation(TextSpan.FromBounds( expression.SpanStart, expression is ArrayCreationExpressionSyntax arrayCreationExpression @@ -172,11 +178,10 @@ expression is ArrayCreationExpressionSyntax arrayCreationExpression : ((ImplicitArrayCreationExpressionSyntax)expression).CloseBracketToken.Span.End))); context.ReportDiagnostic(DiagnosticHelper.CreateWithLocationTags( - Descriptor, - location, - option.Notification, - additionalLocations, - fadingLocations, - properties: null)); + UnnecessaryCodeDescriptor, + additionalUnnecessaryLocations[0], + NotificationOption2.ForSeverity(UnnecessaryCodeDescriptor.DefaultSeverity), + additionalLocations: locations, + additionalUnnecessaryLocations: additionalUnnecessaryLocations)); } } diff --git a/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/CSharpUseCollectionExpressionForBuilderDiagnosticAnalyzer.cs b/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/CSharpUseCollectionExpressionForBuilderDiagnosticAnalyzer.cs index 5236549fb63a8..2bcf1776c0ece 100644 --- a/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/CSharpUseCollectionExpressionForBuilderDiagnosticAnalyzer.cs +++ b/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/CSharpUseCollectionExpressionForBuilderDiagnosticAnalyzer.cs @@ -50,33 +50,47 @@ private void AnalyzeInvocationExpression( if (AnalyzeInvocation(semanticModel, invocationExpression, expressionType, cancellationToken) is not { } analysisResult) return; - var location = analysisResult.DiagnosticLocation; - var additionalLocations = ImmutableArray.Create(invocationExpression.GetLocation()); - var fadingLocations = GetLocationsToFade(analysisResult); - - context.ReportDiagnostic(DiagnosticHelper.CreateWithLocationTags( + var locations = ImmutableArray.Create(invocationExpression.GetLocation()); + context.ReportDiagnostic(DiagnosticHelper.Create( Descriptor, - location, + analysisResult.DiagnosticLocation, option.Notification, - additionalLocations, - fadingLocations, + additionalLocations: locations, properties: null)); + + FadeOutCode(context, analysisResult, locations); } - private static ImmutableArray GetLocationsToFade(AnalysisResult analysisResult) + private void FadeOutCode(SyntaxNodeAnalysisContext context, AnalysisResult analysisResult, ImmutableArray locations) { - using var _ = ArrayBuilder.GetInstance(out var fadingLocations); - fadingLocations.Add(analysisResult.LocalDeclarationStatement.GetLocation()); + var additionalUnnecessaryLocations = ImmutableArray.Create( + analysisResult.LocalDeclarationStatement.GetLocation()); + + context.ReportDiagnostic(DiagnosticHelper.CreateWithLocationTags( + UnnecessaryCodeDescriptor, + additionalUnnecessaryLocations[0], + NotificationOption2.ForSeverity(UnnecessaryCodeDescriptor.DefaultSeverity), + additionalLocations: locations, + additionalUnnecessaryLocations: additionalUnnecessaryLocations, + properties: null)); foreach (var statementMatch in analysisResult.Matches) { - var locations = UseCollectionInitializerHelpers.GetLocationsToFade( + additionalUnnecessaryLocations = UseCollectionInitializerHelpers.GetLocationsToFade( CSharpSyntaxFacts.Instance, statementMatch); - if (!locations.IsDefaultOrEmpty) - fadingLocations.AddRange(locations); - } + if (additionalUnnecessaryLocations.IsDefaultOrEmpty) + continue; - return fadingLocations.ToImmutable(); + // Report the diagnostic at the first unnecessary location. This is the location where the code fix + // will be offered. + context.ReportDiagnostic(DiagnosticHelper.CreateWithLocationTags( + UnnecessaryCodeDescriptor, + additionalUnnecessaryLocations[0], + NotificationOption2.ForSeverity(UnnecessaryCodeDescriptor.DefaultSeverity), + additionalLocations: locations, + additionalUnnecessaryLocations: additionalUnnecessaryLocations, + properties: null)); + } } public static AnalysisResult? AnalyzeInvocation( diff --git a/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/CSharpUseCollectionExpressionForCreateDiagnosticAnalyzer.cs b/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/CSharpUseCollectionExpressionForCreateDiagnosticAnalyzer.cs index 3f43032c5a69f..235d668bb2c9b 100644 --- a/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/CSharpUseCollectionExpressionForCreateDiagnosticAnalyzer.cs +++ b/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/CSharpUseCollectionExpressionForCreateDiagnosticAnalyzer.cs @@ -49,22 +49,28 @@ private void AnalyzeInvocationExpression(SyntaxNodeAnalysisContext context, INam if (!CanReplaceWithCollectionExpression(semanticModel, invocationExpression, expressionType, skipVerificationForReplacedNode: true, cancellationToken)) return; - var location = memberAccess.Name.Identifier.GetLocation(); - var additionalLocations = ImmutableArray.Create(invocationExpression.GetLocation()); - var fadingLocations = ImmutableArray.Create( + var locations = ImmutableArray.Create(invocationExpression.GetLocation()); + var properties = unwrapArgument ? s_unwrapArgumentProperties : null; + + context.ReportDiagnostic(DiagnosticHelper.Create( + Descriptor, + memberAccess.Name.Identifier.GetLocation(), + option.Notification, + additionalLocations: locations, + properties)); + + var additionalUnnecessaryLocations = ImmutableArray.Create( syntaxTree.GetLocation(TextSpan.FromBounds( invocationExpression.SpanStart, invocationExpression.ArgumentList.OpenParenToken.Span.End)), invocationExpression.ArgumentList.CloseParenToken.GetLocation()); - var properties = unwrapArgument ? s_unwrapArgumentProperties : null; - context.ReportDiagnostic(DiagnosticHelper.CreateWithLocationTags( - Descriptor, - location, - option.Notification, - additionalLocations, - fadingLocations, + UnnecessaryCodeDescriptor, + additionalUnnecessaryLocations[0], + NotificationOption2.ForSeverity(UnnecessaryCodeDescriptor.DefaultSeverity), + additionalLocations: locations, + additionalUnnecessaryLocations: additionalUnnecessaryLocations, properties)); } } diff --git a/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/CSharpUseCollectionExpressionForStackAllocDiagnosticAnalyzer.cs b/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/CSharpUseCollectionExpressionForStackAllocDiagnosticAnalyzer.cs index 63945cf9d7153..41a40a7488706 100644 --- a/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/CSharpUseCollectionExpressionForStackAllocDiagnosticAnalyzer.cs +++ b/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/CSharpUseCollectionExpressionForStackAllocDiagnosticAnalyzer.cs @@ -52,20 +52,25 @@ private void AnalyzeImplicitStackAllocExpression(SyntaxNodeAnalysisContext conte return; } - var location = expression.GetFirstToken().GetLocation(); - var additionalLocations = ImmutableArray.Create(expression.GetLocation()); - var fadingLocations = ImmutableArray.Create( + var locations = ImmutableArray.Create(expression.GetLocation()); + context.ReportDiagnostic(DiagnosticHelper.Create( + Descriptor, + expression.GetFirstToken().GetLocation(), + option.Notification, + additionalLocations: locations, + properties: null)); + + var additionalUnnecessaryLocations = ImmutableArray.Create( syntaxTree.GetLocation(TextSpan.FromBounds( expression.SpanStart, expression.CloseBracketToken.Span.End))); context.ReportDiagnostic(DiagnosticHelper.CreateWithLocationTags( - Descriptor, - location, - option.Notification, - additionalLocations, - fadingLocations, - properties: null)); + UnnecessaryCodeDescriptor, + additionalUnnecessaryLocations[0], + NotificationOption2.ForSeverity(UnnecessaryCodeDescriptor.DefaultSeverity), + additionalLocations: locations, + additionalUnnecessaryLocations: additionalUnnecessaryLocations)); } private void AnalyzeExplicitStackAllocExpression(SyntaxNodeAnalysisContext context, INamedTypeSymbol? expressionType) @@ -84,20 +89,25 @@ private void AnalyzeExplicitStackAllocExpression(SyntaxNodeAnalysisContext conte if (matches.IsDefault) return; - var location = expression.GetFirstToken().GetLocation(); - var additionalLocations = ImmutableArray.Create(expression.GetLocation()); - var fadingLocations = ImmutableArray.Create( + var locations = ImmutableArray.Create(expression.GetLocation()); + context.ReportDiagnostic(DiagnosticHelper.Create( + Descriptor, + expression.GetFirstToken().GetLocation(), + option.Notification, + additionalLocations: locations, + properties: null)); + + var additionalUnnecessaryLocations = ImmutableArray.Create( syntaxTree.GetLocation(TextSpan.FromBounds( expression.SpanStart, expression.Type.Span.End))); context.ReportDiagnostic(DiagnosticHelper.CreateWithLocationTags( - Descriptor, - location, - option.Notification, - additionalLocations, - fadingLocations, - properties: null)); + UnnecessaryCodeDescriptor, + additionalUnnecessaryLocations[0], + NotificationOption2.ForSeverity(UnnecessaryCodeDescriptor.DefaultSeverity), + additionalLocations: locations, + additionalUnnecessaryLocations: additionalUnnecessaryLocations)); } public static ImmutableArray> TryGetMatches( diff --git a/src/Analyzers/CSharp/CodeFixes/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessCodeFixProvider.cs index a65ddc32b57fc..d39fcd8698a8b 100644 --- a/src/Analyzers/CSharp/CodeFixes/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessCodeFixProvider.cs @@ -33,6 +33,11 @@ public InvokeDelegateWithConditionalAccessCodeFixProvider() public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create(IDEDiagnosticIds.InvokeDelegateWithConditionalAccessId); + // Filter out the diagnostics we created for the faded out code. We don't want + // to try to fix those as well as the normal diagnostics we created. + protected override bool IncludeDiagnosticDuringFixAll(Diagnostic diagnostic) + => !diagnostic.Properties.ContainsKey(WellKnownDiagnosticTags.Unnecessary); + public override Task RegisterCodeFixesAsync(CodeFixContext context) { RegisterCodeFix(context, CSharpAnalyzersResources.Simplify_delegate_invocation, nameof(CSharpAnalyzersResources.Simplify_delegate_invocation)); diff --git a/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForEmptyCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForEmptyCodeFixProvider.cs index 725312f4af43f..3a96e082c0c30 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForEmptyCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseCollectionExpression/CSharpUseCollectionExpressionForEmptyCodeFixProvider.cs @@ -34,6 +34,9 @@ public CSharpUseCollectionExpressionForEmptyCodeFixProvider() public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create(IDEDiagnosticIds.UseCollectionExpressionForEmptyDiagnosticId); + protected override bool IncludeDiagnosticDuringFixAll(Diagnostic diagnostic) + => !diagnostic.Descriptor.ImmutableCustomTags().Contains(WellKnownDiagnosticTags.Unnecessary); + public override Task RegisterCodeFixesAsync(CodeFixContext context) { RegisterCodeFix(context, CSharpCodeFixesResources.Use_collection_expression, IDEDiagnosticIds.UseCollectionExpressionForEmptyDiagnosticId); diff --git a/src/Analyzers/CSharp/CodeFixes/UseThrowExpression/UseThrowExpressionCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseThrowExpression/UseThrowExpressionCodeFixProvider.cs index 92a4279319416..1ddcbd5708559 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseThrowExpression/UseThrowExpressionCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseThrowExpression/UseThrowExpressionCodeFixProvider.cs @@ -33,6 +33,9 @@ public UseThrowExpressionCodeFixProvider() public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(IDEDiagnosticIds.UseThrowExpressionDiagnosticId); + protected override bool IncludeDiagnosticDuringFixAll(Diagnostic diagnostic) + => !diagnostic.Descriptor.ImmutableCustomTags().Contains(WellKnownDiagnosticTags.Unnecessary); + public override Task RegisterCodeFixesAsync(CodeFixContext context) { RegisterCodeFix(context, AnalyzersResources.Use_throw_expression, nameof(AnalyzersResources.Use_throw_expression)); diff --git a/src/Analyzers/CSharp/Tests/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessTests.cs b/src/Analyzers/CSharp/Tests/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessTests.cs index 457fa1c2a131d..c73e8ccd6c7c0 100644 --- a/src/Analyzers/CSharp/Tests/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessTests.cs +++ b/src/Analyzers/CSharp/Tests/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessTests.cs @@ -36,10 +36,42 @@ class C void Goo() { - var v = a; + [||]var v = a; if (v != null) { - [||]v(); + v(); + } + } + } + """, + """ + class C + { + System.Action a; + + void Goo() + { + a?.Invoke(); + } + } + """); + } + + [Fact] + public async Task TestOnIf() + { + await TestInRegularAndScript1Async( + """ + class C + { + System.Action a; + + void Goo() + { + var v = a; + [||]if (v != null) + { + v(); } } } @@ -121,10 +153,10 @@ class C void Goo() { - var v = a; + [||]var v = a; if (null != v) { - [||]v(); + v(); } } } @@ -153,9 +185,9 @@ class C void Goo() { - var v = a; + [||]var v = a; if (null != v) - [||]v(); + v(); } } """, @@ -184,10 +216,10 @@ class C void Goo() { bool b = true; - var v = b ? a : null; + [||]var v = b ? a : null; if (v != null) { - [||]v(); + v(); } } } @@ -267,9 +299,9 @@ class C void Goo() { var v = a, x = a; - if (v != null) + [||]if (v != null) { - [||]v(); + v(); } } } @@ -332,9 +364,9 @@ class C void Goo() { var v = a; - if (v != null) + [||]if (v != null) { - [||]v(); + v(); } v = null; @@ -370,9 +402,9 @@ class C void M() { - if (this.E != null) + [||]if (this.E != null) { - [||]this.E(this, EventArgs.Empty); + this.E(this, EventArgs.Empty); } } } @@ -443,9 +475,9 @@ void M() if (true != true) { } - else if (this.E != null) + else [||]if (this.E != null) { - [||]this.E(this, EventArgs.Empty); + this.E(this, EventArgs.Empty); } } } @@ -471,6 +503,45 @@ void M() """); } + [Fact] + public async Task TestInElseClause2() + { + await TestInRegularAndScript1Async( + """ + using System; + + class C + { + public event EventHandler E; + + void M() + { + if (true != true) + { + } + else [||]if (this.E != null) + this.E(this, EventArgs.Empty); + } + } + """, + """ + using System; + + class C + { + public event EventHandler E; + + void M() + { + if (true != true) + { + } + else this.E?.Invoke(this, EventArgs.Empty); + } + } + """); + } + [Fact] public async Task TestTrivia1() { @@ -482,10 +553,10 @@ class C void Goo() { // Comment - var v = a; + [||]var v = a; if (v != null) { - [||]v(); // Comment2 + v(); // Comment2 } } } @@ -514,9 +585,9 @@ class C void Goo() { // Comment - if (a != null) + [||]if (a != null) { - [||]a(); // Comment2 + a(); // Comment2 } } } @@ -545,8 +616,8 @@ class C void Goo() { // Comment - var v = a; - if (v != null) { [||]v(); /* 123 */ } // trails + [||]var v = a; + if (v != null) { v(); /* 123 */ } // trails System.Console.WriteLine(); } } @@ -575,7 +646,7 @@ class C System.Action a; void Goo() { - if (a != null) { [||]a(); /* 123 */ } // trails + [||]if (a != null) { a(); /* 123 */ } // trails System.Console.WriteLine(); } } @@ -593,6 +664,41 @@ void Goo() """); } + /// + /// tests locations where the fix is offered. + /// + [Fact] + public async Task TestFixOfferedOnIf() + { + await TestInRegularAndScript1Async( + """ + class C + { + System.Action a; + + void Goo() + { + var v = a; + [||]if (v != null) + { + v(); + } + } + } + """, + """ + class C + { + System.Action a; + + void Goo() + { + a?.Invoke(); + } + } + """); + } + /// /// tests locations where the fix is offered. /// @@ -637,6 +743,24 @@ class C { System.Action a; + void Goo() + { + [||]var v = a; + v?.Invoke(); + } + } + """); + } + + [Fact] + public async Task TestMissingOnConditionalInvocation2() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + System.Action a; + void Goo() { var v = a; @@ -748,9 +872,9 @@ void Goo() { var v = a; int x; - if (v != null) + [||]if (v != null) { - [||]v(); + v(); } } } @@ -782,9 +906,9 @@ class C int Goo() { var v = a; - if (v != null) + [||]if (v != null) { - [||]return v(); + return v(); } } } @@ -803,9 +927,9 @@ class C void Goo() { Action v = () => {}; - if (v != null) + [||]if (v != null) { - [||]v(); + v(); } } } @@ -836,9 +960,9 @@ class C void Goo() { Action v = (() => {}); - if (v != null) + [||]if (v != null) { - [||]v(); + v(); } } } @@ -869,9 +993,9 @@ class C void Goo() { Action v = delegate {}; - if (v != null) + [||]if (v != null) { - [||]v(); + v(); } } } @@ -902,9 +1026,9 @@ class C void Goo() { Action v = Console.WriteLine; - if (v != null) + [||]if (v != null) { - [||]v(); + v(); } } } @@ -934,8 +1058,8 @@ class C { void M() { - if (Event != null) - [||]Event.Invoke(this, EventArgs.Empty); + [||]if (Event != null) + Event.Invoke(this, EventArgs.Empty); } event EventHandler Event; @@ -967,10 +1091,10 @@ class C void Goo() { - var v = a; + [||]var v = a; if (v != null) { - [||]v.Invoke(); + v.Invoke(); } } } diff --git a/src/Analyzers/CSharp/Tests/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessTests_FixAllTests.cs b/src/Analyzers/CSharp/Tests/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessTests_FixAllTests.cs index c81e8d548a473..5079cc29cec89 100644 --- a/src/Analyzers/CSharp/Tests/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessTests_FixAllTests.cs +++ b/src/Analyzers/CSharp/Tests/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessTests_FixAllTests.cs @@ -21,6 +21,78 @@ await TestInRegularAndScriptAsync( { System.Action a; + void Goo() + { + {|FixAllInDocument:var|} v = a; + if (v != null) + { + v(); + } + + var x = a; + if (x != null) + { + x(); + } + } +}", +@"class C +{ + System.Action a; + + void Goo() + { + a?.Invoke(); + + a?.Invoke(); + } +}"); + } + + [Fact] + public async Task TestFixAllInDocument2() + { + await TestInRegularAndScriptAsync( +@"class C +{ + System.Action a; + + void Goo() + { + var v = a; + {|FixAllInDocument:if|} (v != null) + { + v(); + } + + var x = a; + if (x != null) + { + x(); + } + } +}", +@"class C +{ + System.Action a; + + void Goo() + { + a?.Invoke(); + + a?.Invoke(); + } +}"); + } + + [Fact] + public async Task TestFixAllInDocument3() + { + await TestInRegularAndScriptAsync( +@"class C +{ + System.Action a; + void Goo() { var v = a; @@ -50,7 +122,79 @@ void Goo() } [Fact] - public async Task TestFixAllInDocument2() + public async Task TestFixAllInDocument4() + { + await TestInRegularAndScriptAsync( +@"class C +{ + System.Action a; + + void Goo() + { + var v = a; + if (v != null) + { + v(); + } + + {|FixAllInDocument:var|} x = a; + if (x != null) + { + x(); + } + } +}", +@"class C +{ + System.Action a; + + void Goo() + { + a?.Invoke(); + + a?.Invoke(); + } +}"); + } + + [Fact] + public async Task TestFixAllInDocument5() + { + await TestInRegularAndScriptAsync( +@"class C +{ + System.Action a; + + void Goo() + { + var v = a; + if (v != null) + { + v(); + } + + var x = a; + {|FixAllInDocument:if|} (x != null) + { + x(); + } + } +}", +@"class C +{ + System.Action a; + + void Goo() + { + a?.Invoke(); + + a?.Invoke(); + } +}"); + } + + [Fact] + public async Task TestFixAllInDocument6() { await TestInRegularAndScriptAsync( @"class C diff --git a/src/Analyzers/CSharp/Tests/UseCollectionExpression/UseCollectionExpressionForArrayTests.cs b/src/Analyzers/CSharp/Tests/UseCollectionExpression/UseCollectionExpressionForArrayTests.cs index e6b052d43c1f1..59817dad68720 100644 --- a/src/Analyzers/CSharp/Tests/UseCollectionExpression/UseCollectionExpressionForArrayTests.cs +++ b/src/Analyzers/CSharp/Tests/UseCollectionExpression/UseCollectionExpressionForArrayTests.cs @@ -214,7 +214,7 @@ public async Task TestWithCompatibleExplicitArrays1() TestCode = """ class C { - object[] i = [|new|] object[] { "" }; + object[] i = [|[|new|] object[]|] { "" }; } """, FixedCode = """ @@ -235,7 +235,7 @@ public async Task TestWithCompatibleExplicitArrays2() TestCode = """ class C { - object[] i = [|new|] object[] + object[] i = [|[|new|] object[]|] { "" }; @@ -262,7 +262,7 @@ public async Task TestWithCompatibleExplicitArrays_Empty() TestCode = """ class C { - object[] i = [|new|] object[] { }; + object[] i = [|[|new|] object[]|] { }; } """, FixedCode = """ @@ -283,7 +283,7 @@ public async Task TestWithCompatibleExplicitArrays_TrailingComma() TestCode = """ class C { - object[] i = [|new|] object[] { "", }; + object[] i = [|[|new|] object[]|] { "", }; } """, FixedCode = """ @@ -304,7 +304,7 @@ public async Task TestWithExplicitArray_ExplicitSize() TestCode = """ class C { - string[] i = [|new|] string[1] { "" }; + string[] i = [|[|new|] string[1]|] { "" }; } """, FixedCode = """ @@ -385,7 +385,7 @@ public async Task TestWithCompatibleImplicitArrays1() TestCode = """ class C { - string[] i = [|new|][] { "" }; + string[] i = [|[|new|][]|] { "" }; } """, FixedCode = """ @@ -406,7 +406,7 @@ public async Task TestWithCompatibleImplicitArrays2() TestCode = """ class C { - string[] i = [|new|][] + string[] i = [|[|new|][]|] { "" }; @@ -448,7 +448,7 @@ public async Task TestWithCompatibleImplicitArrays_TrailingComma() TestCode = """ class C { - string[] i = [|new|][] { "", }; + string[] i = [|[|new|][]|] { "", }; } """, FixedCode = """ @@ -566,7 +566,7 @@ public async Task TestTargetTypedToField() TestCode = """ class C { - private int[] X = [|new|] int[] { 1 }; + private int[] X = [|[|new|] int[]|] { 1 }; } """, FixedCode = """ @@ -587,7 +587,7 @@ public async Task TestTargetTypedToProperty() TestCode = """ class C { - private int[] X { get; } = [|new|] int[] { 1 }; + private int[] X { get; } = [|[|new|] int[]|] { 1 }; } """, FixedCode = """ @@ -610,7 +610,7 @@ class C { void M() { - var c = (int[])[|new|] int[] { 1 }; + var c = (int[])[|[|new|] int[]|] { 1 }; } } """, @@ -711,7 +711,7 @@ class C { void M(int[] x) { - var c = true ? [|new|] int[] { 1 } : x; + var c = true ? [|[|new|] int[]|] { 1 } : x; } } """, @@ -738,7 +738,7 @@ class C { void M(int[] x) { - var c = true ? x : [|new|] int[] { 1 }; + var c = true ? x : [|[|new|] int[]|] { 1 }; } } """, @@ -765,7 +765,7 @@ class C { void M(int[] x) { - int[] c = true ? null : [|new|] int[] { 1 }; + int[] c = true ? null : [|[|new|] int[]|] { 1 }; } } """, @@ -810,7 +810,7 @@ class C { void M(int[] x, bool b) { - var c = b switch { true => x, false => [|new|] int[] { 1 } }; + var c = b switch { true => x, false => [|[|new|] int[]|] { 1 } }; } } """, @@ -837,7 +837,7 @@ class C { void M(int[] x, bool b) { - var c = b switch { false => [|new|] int[] { 1 }, true => x }; + var c = b switch { false => [|[|new|] int[]|] { 1 }, true => x }; } } """, @@ -864,7 +864,7 @@ class C { void M(int[] x, bool b) { - int[] c = b switch { false => [|new|] int[] { 1 }, true => null }; + int[] c = b switch { false => [|[|new|] int[]|] { 1 }, true => null }; } } """, @@ -927,7 +927,7 @@ class C { void M(int[] x, bool b) { - var c = new[] { [|new|][] { 1, 2, 3 }, x }; + var c = new[] { [|[|new|][]|] { 1, 2, 3 }, x }; } } """, @@ -954,7 +954,7 @@ class C { void M(int[] x, bool b) { - var c = new[] { x, [|new|][] { 1, 2, 3 } }; + var c = new[] { x, [|[|new|][]|] { 1, 2, 3 } }; } } """, @@ -999,7 +999,7 @@ class C { void M(int[] x, bool b) { - int[][] c = [|new|][] { new[] { 1, 2, 3 } }; + int[][] c = [|[|new|][]|] { new[] { 1, 2, 3 } }; } } """, @@ -1017,7 +1017,9 @@ void M(int[] x, bool b) ExpectedDiagnostics = { // /0/Test0.cs(5,22): info IDE0300: Collection initialization can be simplified - VerifyCS.Diagnostic().WithSpan(5, 22, 5, 25).WithSpan(5, 22, 5, 39).WithSpan(5, 22, 5, 27).WithSeverity(DiagnosticSeverity.Info) + VerifyCS.Diagnostic().WithSpan(5, 22, 5, 25).WithSpan(5, 22, 5, 39).WithSeverity(DiagnosticSeverity.Info), + // /0/Test0.cs(5,22): hidden IDE0300: Collection initialization can be simplified + VerifyCS.Diagnostic().WithSpan(5, 22, 5, 27).WithSpan(5, 22, 5, 39).WithSpan(5, 22, 5, 27).WithSeverity(DiagnosticSeverity.Hidden), } }, LanguageVersion = LanguageVersion.CSharp12, @@ -1035,7 +1037,7 @@ class C { void M() { - X([|new|] int[] { 1, 2, 3 }); + X([|[|new|] int[]|] { 1, 2, 3 }); } void X(int[] x) { } @@ -1084,7 +1086,7 @@ public async Task TestTargetTypedAttributeArgument1() await new VerifyCS.Test { TestCode = """ - [X([|new|] int[] { 1, 2, 3 })] + [X([|[|new|] int[]|] { 1, 2, 3 })] class C { } @@ -1119,7 +1121,7 @@ class C { int[] M() { - return [|new|] int[] { 1, 2, 3 }; + return [|[|new|] int[]|] { 1, 2, 3 }; } } """, @@ -1146,7 +1148,7 @@ class C { void M(int[] x) { - x = [|new|] int[] { 1, 2, 3 }; + x = [|[|new|] int[]|] { 1, 2, 3 }; } } """, @@ -1177,7 +1179,7 @@ void M() { var v = new C { - X = [|new|] int[] { 1, 2, 3 }, + X = [|[|new|] int[]|] { 1, 2, 3 }, }; } } @@ -1210,7 +1212,7 @@ class C { void M(int[] x) { - var y = x ?? [|new|] int[] { 1, 2, 3 }; + var y = x ?? [|[|new|] int[]|] { 1, 2, 3 }; } } """, @@ -1458,7 +1460,7 @@ public async Task TestInitializerFormatting1_Explicit() TestCode = """ class C { - int[] i = [|new|] int[] { 1, 2, 3 }; + int[] i = [|[|new|] int[]|] { 1, 2, 3 }; } """, FixedCode = """ @@ -1480,7 +1482,7 @@ public async Task TestInitializerFormatting2_Explicit() class C { int[] i = - [|new|] int[] { 1, 2, 3 }; + [|[|new|] int[]|] { 1, 2, 3 }; } """, FixedCode = """ @@ -1502,7 +1504,7 @@ public async Task TestInitializerFormatting3_Explicit() TestCode = """ class C { - int[] i = [|new|] int[] { + int[] i = [|[|new|] int[]|] { 1, 2, 3 }; } @@ -1527,7 +1529,7 @@ public async Task TestInitializerFormatting4_Explicit() TestCode = """ class C { - int[] i = [|new|] int[] + int[] i = [|[|new|] int[]|] { 1, 2, 3 }; @@ -1555,7 +1557,7 @@ public async Task TestInitializerFormatting5_Explicit() class C { int[] i = - [|new|] int[] + [|[|new|] int[]|] { 1, 2, 3 }; @@ -1583,7 +1585,7 @@ public async Task TestInitializerFormatting6_Explicit() class C { int[] i = - [|new|] int[] { + [|[|new|] int[]|] { 1, 2, 3 }; } @@ -1610,7 +1612,7 @@ public async Task TestInitializerFormatting7_Explicit() class C { int[] i = - [|new|] int[] + [|[|new|] int[]|] { 1, 2, 3 }; @@ -1638,7 +1640,7 @@ public async Task TestInitializerFormatting8_Explicit() class C { int[] i = - [|new|] int[] { + [|[|new|] int[]|] { 1, 2, 3 }; } @@ -1664,7 +1666,7 @@ public async Task TestInitializerFormatting9_Explicit() TestCode = """ class C { - int[] i = [|new|] int[] { + int[] i = [|[|new|] int[]|] { 1, 2, 3 }; } @@ -1691,7 +1693,7 @@ class C { int[] i = - [|new|] int[] + [|[|new|] int[]|] { 1, 2, 3 }; @@ -1719,7 +1721,7 @@ public async Task TestInitializerFormatting1_Implicit() TestCode = """ class C { - int[] i = [|new|][] { 1, 2, 3 }; + int[] i = [|[|new|][]|] { 1, 2, 3 }; } """, FixedCode = """ @@ -1741,7 +1743,7 @@ public async Task TestInitializerFormatting2_Implicit() class C { int[] i = - [|new|][] { 1, 2, 3 }; + [|[|new|][]|] { 1, 2, 3 }; } """, FixedCode = """ @@ -1763,7 +1765,7 @@ public async Task TestInitializerFormatting3_Implicit() TestCode = """ class C { - int[] i = [|new|][] { + int[] i = [|[|new|][]|] { 1, 2, 3 }; } @@ -1788,7 +1790,7 @@ public async Task TestInitializerFormatting4_Implicit() TestCode = """ class C { - int[] i = [|new|][] + int[] i = [|[|new|][]|] { 1, 2, 3 }; @@ -1816,7 +1818,7 @@ public async Task TestInitializerFormatting5_Implicit() class C { int[] i = - [|new|][] + [|[|new|][]|] { 1, 2, 3 }; @@ -1844,7 +1846,7 @@ public async Task TestInitializerFormatting6_Implicit() class C { int[] i = - [|new|][] { + [|[|new|][]|] { 1, 2, 3 }; } @@ -1871,7 +1873,7 @@ public async Task TestInitializerFormatting7_Implicit() class C { int[] i = - [|new|][] + [|[|new|][]|] { 1, 2, 3 }; @@ -1899,7 +1901,7 @@ public async Task TestInitializerFormatting8_Implicit() class C { int[] i = - [|new|][] { + [|[|new|][]|] { 1, 2, 3 }; } @@ -1925,7 +1927,7 @@ public async Task TestInitializerFormatting9_Implicit() TestCode = """ class C { - int[] i = [|new|][] { + int[] i = [|[|new|][]|] { 1, 2, 3 }; } @@ -1952,7 +1954,7 @@ class C { int[] i = - [|new|][] + [|[|new|][]|] { 1, 2, 3 }; @@ -1990,11 +1992,11 @@ class WellKnownDiagnosticTags class C { private static readonly string s_enforceOnBuildNeverTag; - private static readonly string[] s_microsoftCustomTags = [|new|] string[] { WellKnownDiagnosticTags.Telemetry }; - private static readonly string[] s_editAndContinueCustomTags = [|new|] string[] { WellKnownDiagnosticTags.EditAndContinue, WellKnownDiagnosticTags.Telemetry, WellKnownDiagnosticTags.NotConfigurable, s_enforceOnBuildNeverTag }; - private static readonly string[] s_unnecessaryCustomTags = [|new|] string[] { WellKnownDiagnosticTags.Unnecessary, WellKnownDiagnosticTags.Telemetry }; - private static readonly string[] s_notConfigurableCustomTags = [|new|] string[] { WellKnownDiagnosticTags.NotConfigurable, s_enforceOnBuildNeverTag, WellKnownDiagnosticTags.Telemetry }; - private static readonly string[] s_unnecessaryAndNotConfigurableCustomTags = [|new|] string[] { WellKnownDiagnosticTags.Unnecessary, WellKnownDiagnosticTags.NotConfigurable, s_enforceOnBuildNeverTag, WellKnownDiagnosticTags.Telemetry }; + private static readonly string[] s_microsoftCustomTags = [|[|new|] string[]|] { WellKnownDiagnosticTags.Telemetry }; + private static readonly string[] s_editAndContinueCustomTags = [|[|new|] string[]|] { WellKnownDiagnosticTags.EditAndContinue, WellKnownDiagnosticTags.Telemetry, WellKnownDiagnosticTags.NotConfigurable, s_enforceOnBuildNeverTag }; + private static readonly string[] s_unnecessaryCustomTags = [|[|new|] string[]|] { WellKnownDiagnosticTags.Unnecessary, WellKnownDiagnosticTags.Telemetry }; + private static readonly string[] s_notConfigurableCustomTags = [|[|new|] string[]|] { WellKnownDiagnosticTags.NotConfigurable, s_enforceOnBuildNeverTag, WellKnownDiagnosticTags.Telemetry }; + private static readonly string[] s_unnecessaryAndNotConfigurableCustomTags = [|[|new|] string[]|] { WellKnownDiagnosticTags.Unnecessary, WellKnownDiagnosticTags.NotConfigurable, s_enforceOnBuildNeverTag, WellKnownDiagnosticTags.Telemetry }; } } """, @@ -2035,7 +2037,7 @@ class C { void M(int i, int j) { - int[] r = [|new|] int[1]; + int[] r = [|[|new|] int[1]|]; r[0] = 1 + 2; } @@ -2072,7 +2074,7 @@ class C { void M(int i, int j) { - int[] r = [|new|] int[2]; + int[] r = [|[|new|] int[2]|]; r[0] = 1 + 2; r[1] = 3 + @@ -2113,7 +2115,7 @@ class C { void M() { - int[] r = [|new|] int[0]; + int[] r = [|[|new|] int[0]|]; } } """, @@ -2360,7 +2362,7 @@ class C { void M(int i, int j) { - int[] r = [|new|] int[1]; + int[] r = [|[|new|] int[1]|]; r[0] = i; } } @@ -2392,7 +2394,7 @@ class C { void M(int i, int j) { - int[] r = [|new|] int[1]; + int[] r = [|[|new|] int[1]|]; r[0] = i; r[0] = j; } @@ -2426,7 +2428,7 @@ class C { void M(int i, int j) { - int[] r = [|new|] int[2]; + int[] r = [|[|new|] int[2]|]; r[0] = i; r[1] = j; } @@ -2460,7 +2462,7 @@ class C void M(int i, int j) { const int v = 1; - int[] r = [|new|] int[2]; + int[] r = [|[|new|] int[2]|]; r[0] = i; r[v] = j; } @@ -2564,7 +2566,7 @@ class C { void M(int i, int j) { - int[][] r = [|new|] int[2][]; + int[][] r = [|[|new|] int[2][]|]; r[0] = null; r[1] = null; } @@ -2597,9 +2599,9 @@ class C { void M(int i, int j) { - int[][] r = [|new|] int[2][]; - r[0] = [|new|][] { 1 }; - r[1] = [|new|] int[] { 2 }; + int[][] r = [|[|new|] int[2][]|]; + r[0] = [|[|new|][]|] { 1 }; + r[1] = [|[|new|] int[]|] { 2 }; } } """, @@ -2630,11 +2632,11 @@ class C { void M(int i, int j) { - int[][] r = [|new|] int[2][]; + int[][] r = [|[|new|] int[2][]|]; // Leading - r[0] = [|new|][] { 1 }; // Trailing - r[1] = [|new|] int[] { 2 }; + r[0] = [|[|new|][]|] { 1 }; // Trailing + r[1] = [|[|new|] int[]|] { 2 }; } } """, @@ -2670,14 +2672,14 @@ class C { void M(int i, int j) { - int[][] r = [|new|] int[2][]; + int[][] r = [|[|new|] int[2][]|]; - r[0] = [|new|][] + r[0] = [|[|new|][]|] { // Leading 1 // Trailing }; - r[1] = [|new|] int[] { 2 }; + r[1] = [|[|new|] int[]|] { 2 }; } } """, @@ -2784,10 +2786,10 @@ public async Task TestWithDifferentNewLines(string endOfLine) public static readonly IEnumerable EmptyOrConstantsOnly = new object[][] { - new [] { "[|new|] int[0]", "[]" }, - new [] { "[|new|] int[] { }", "[]" }, - new [] { "[|new|] int[] { 1, 2, 3 }", "[1, 2, 3]" }, - new [] { "[|new|][] { 1, 2, 3 }", "[1, 2, 3]" }, + new [] { "[|[|new|] int[0]|]", "[]" }, + new [] { "[|[|new|] int[]|] { }", "[]" }, + new [] { "[|[|new|] int[]|] { 1, 2, 3 }", "[1, 2, 3]" }, + new [] { "[|[|new|][]|] { 1, 2, 3 }", "[1, 2, 3]" }, }; [Theory, MemberData(nameof(EmptyOrConstantsOnly))] @@ -3099,7 +3101,7 @@ class C { void M(int i) { - ReadOnlySpan s = [|new|][] { i }; + ReadOnlySpan s = [|[|new|][]|] { i }; } } """, @@ -3135,7 +3137,7 @@ class C { void M(int i) { - ReadOnlySpan s = [|new|][] { i }; + ReadOnlySpan s = [|[|new|][]|] { i }; ReadOnlySpan t; } } @@ -3175,7 +3177,7 @@ class C ReadOnlySpan M(int i) { - ReadOnlySpan s = [|new|][] { i }; + ReadOnlySpan s = [|[|new|][]|] { i }; ReadOnlySpan t = globalArray; return t; } @@ -3217,7 +3219,7 @@ class C { void M(int i) { - ReadOnlySpan s = [|new|][] { i }; + ReadOnlySpan s = [|[|new|][]|] { i }; ReadOnlySpan t = s; } } @@ -3255,7 +3257,7 @@ class C { void M(int i) { - ReadOnlySpan s = [|new|][] { i }; + ReadOnlySpan s = [|[|new|][]|] { i }; X(s); } @@ -3297,7 +3299,7 @@ class C { ReadOnlySpan M(int i) { - ReadOnlySpan s = [|new|][] { i }; + ReadOnlySpan s = [|[|new|][]|] { i }; return X(s); } @@ -3339,7 +3341,7 @@ class C { void M(int i) { - ReadOnlySpan s = [|new|][] { i }; + ReadOnlySpan s = [|[|new|][]|] { i }; s.Slice(0, 1); } } @@ -3377,7 +3379,7 @@ class C { string M(int i) { - ReadOnlySpan s = [|new|][] { i }; + ReadOnlySpan s = [|[|new|][]|] { i }; return s.ToString(); } } @@ -3415,7 +3417,7 @@ class C { ReadOnlySpan M(int i) { - ReadOnlySpan s = [|new|][] { i }; + ReadOnlySpan s = [|[|new|][]|] { i }; return X(s.Slice(0, 1)); } @@ -3457,7 +3459,7 @@ class C { ReadOnlySpan M(int i) { - ReadOnlySpan s = [|new|][] { i }; + ReadOnlySpan s = [|[|new|][]|] { i }; return X(s[0..1]); } @@ -3499,7 +3501,7 @@ class C { int M(int i) { - ReadOnlySpan s = [|new|][] { i }; + ReadOnlySpan s = [|[|new|][]|] { i }; return s[0]; } } @@ -3537,7 +3539,7 @@ class C { int M(int i) { - ReadOnlySpan s = [|new|][] { i }; + ReadOnlySpan s = [|[|new|][]|] { i }; return s.Length; } } @@ -3575,7 +3577,7 @@ class C { int M(int i) { - ReadOnlySpan s = [|new|][] { i }; + ReadOnlySpan s = [|[|new|][]|] { i }; return nameof(s).Length; } } @@ -3956,7 +3958,7 @@ class C { ReadOnlySpan M(int i) { - ReadOnlySpan span = [|new|][] { i }; + ReadOnlySpan span = [|[|new|][]|] { i }; X(span, out var v); return v; } @@ -4000,7 +4002,7 @@ class C { void M(int i) { - ReadOnlySpan span = [|new|][] { i }; + ReadOnlySpan span = [|[|new|][]|] { i }; X(span, out var v); } @@ -4042,7 +4044,7 @@ class C { ReadOnlySpan M(int i) { - ReadOnlySpan span = [|new|][] { i }; + ReadOnlySpan span = [|[|new|][]|] { i }; X(span, out var v); return v.Slice(0, 1); } @@ -4082,7 +4084,7 @@ class C { void M(bool b) { - var v = b ? [|new|][] { "a" } : [|new|][] { "b" }; + var v = b ? [|[|new|][]|] { "a" } : [|[|new|][]|] { "b" }; } } """, @@ -4119,7 +4121,7 @@ class C { void M(bool b) { - var v = b ? [|new|] string[] { "a" } : [|new|] string[] { "b" }; + var v = b ? [|[|new|] string[]|] { "a" } : [|[|new|] string[]|] { "b" }; } } """, @@ -4182,7 +4184,7 @@ class C { void M() { - Func f = () => [|new|] int[] { 1, 2, 3 }; + Func f = () => [|[|new|] int[]|] { 1, 2, 3 }; } } """, @@ -4262,7 +4264,7 @@ class C { (int A, int B)[] M() { - return [|new|][] { (A: 1, 2) }; + return [|[|new|][]|] { (A: 1, 2) }; } } """, @@ -4340,7 +4342,7 @@ class C { void M(bool b) { - object falsePositive = new[] { [|new|][] { 1 }, [|new|][] { 1 } }; + object falsePositive = new[] { [|[|new|][]|] { 1 }, [|[|new|][]|] { 1 } }; } } """, diff --git a/src/Analyzers/CSharp/Tests/UseCollectionExpression/UseCollectionExpressionForBuilderTests.cs b/src/Analyzers/CSharp/Tests/UseCollectionExpression/UseCollectionExpressionForBuilderTests.cs index 0a078cedd53c6..6875f996a24e6 100644 --- a/src/Analyzers/CSharp/Tests/UseCollectionExpression/UseCollectionExpressionForBuilderTests.cs +++ b/src/Analyzers/CSharp/Tests/UseCollectionExpression/UseCollectionExpressionForBuilderTests.cs @@ -58,9 +58,9 @@ public void Clear() { } public static readonly IEnumerable SuccessCreationPatterns = new[] { - new[] {"var builder = ImmutableArray.[|CreateBuilder|]();" }, - new[] {"var builder = ArrayBuilder.[|GetInstance|]();" }, - new[] {"using var _ = ArrayBuilder.[|GetInstance|](out var builder);" }, + new[] {"[|var builder = ImmutableArray.[|CreateBuilder|]();|]" }, + new[] {"[|var builder = ArrayBuilder.[|GetInstance|]();|]" }, + new[] {"[|using var _ = ArrayBuilder.[|GetInstance|](out var builder);|]" }, }; [Theory, MemberData(nameof(FailureCreationPatterns))] @@ -122,7 +122,7 @@ class C ImmutableArray M() { {{pattern}} - builder.Add(0); + [|builder.Add(|]0); return builder.ToImmutable(); } } @@ -156,7 +156,7 @@ class C void M() { {{pattern}} - builder.Add(0); + [|builder.Add(|]0); var v = (ImmutableArray)builder.ToImmutable(); } } @@ -214,7 +214,7 @@ class C void M() { {{pattern}} - builder.Add(0); + [|builder.Add(|]0); Goo(builder.ToImmutable()); } @@ -251,8 +251,8 @@ class C { void M() { - var builder = ImmutableArray.[|CreateBuilder|](1); - builder.Add(0); + [|var builder = ImmutableArray.[|CreateBuilder|](1);|] + [|builder.Add(|]0); Goo(builder.ToImmutable()); } @@ -289,8 +289,8 @@ class C { void M() { - var builder = ArrayBuilder.[|GetInstance|](1); - builder.Add(0); + [|var builder = ArrayBuilder.[|GetInstance|](1);|] + [|builder.Add(|]0); Goo(builder.ToImmutable()); } @@ -327,8 +327,8 @@ class C { void M() { - using var _ = ArrayBuilder.[|GetInstance|](1, out var builder); - builder.Add(0); + [|using var _ = ArrayBuilder.[|GetInstance|](1, out var builder);|] + [|builder.Add(|]0); Goo(builder.ToImmutable()); } @@ -416,8 +416,8 @@ class C void M(int[] x) { {{pattern}} - builder.Add(0); - foreach (var y in x) + [|builder.Add(|]0); + [|foreach (var y in |]x) builder.Add(y); Goo(builder.ToImmutable()); @@ -457,8 +457,8 @@ class C void M(int[] x) { {{pattern}} - builder.Add(0); - foreach (var y in x) + [|builder.Add(|]0); + [|foreach (var y in |]x) { builder.Add(y); } @@ -560,12 +560,12 @@ class C void M(int[] x, int[] y) { {{pattern}} - builder.Add(0); - foreach (var z in x) + [|builder.Add(|]0); + [|foreach (var z in |]x) { builder.Add(z); } - foreach (var z in y) + [|foreach (var z in |]y) { builder.Add(z); } @@ -607,12 +607,12 @@ class C void M(int[] x, int[] y) { {{pattern}} - foreach (var z in x) + [|foreach (var z in |]x) { builder.Add(z); } - builder.Add(0); - foreach (var z in y) + [|builder.Add(|]0); + [|foreach (var z in |]y) { builder.Add(z); } @@ -654,15 +654,15 @@ class C void M(int[] x, int[] y) { {{pattern}} - foreach (var z in x) + [|foreach (var z in |]x) { builder.Add(z); } - foreach (var z in y) + [|foreach (var z in |]y) { builder.Add(z); } - builder.Add(0); + [|builder.Add(|]0); Goo(builder.ToImmutable()); } @@ -871,7 +871,7 @@ class C void M(int[] x) { {{pattern}} - builder.AddRange(x); + [|builder.AddRange(|]x); Goo(builder.ToImmutable()); } @@ -909,7 +909,7 @@ class C void M(int[] x) { {{pattern}} - builder.AddRange(1); + [|builder.AddRange(|]1); Goo(builder.ToImmutable()); } @@ -947,7 +947,7 @@ class C void M(int[] x) { {{pattern}} - builder.AddRange(1, 2, 3); + [|builder.AddRange(|]1, 2, 3); Goo(builder.ToImmutable()); } @@ -1009,8 +1009,8 @@ class C { void M() { - var builder = ImmutableArray.[|CreateBuilder|](1); - builder.Add(0); + [|var builder = ImmutableArray.[|CreateBuilder|](1);|] + [|builder.Add(|]0); Goo(builder.MoveToImmutable()); } @@ -1047,8 +1047,8 @@ class C { void M() { - var builder = ArrayBuilder.[|GetInstance|](); - builder.Add(0); + [|var builder = ArrayBuilder.[|GetInstance|]();|] + [|builder.Add(|]0); Goo(builder.ToImmutableAndFree()); } @@ -1085,8 +1085,8 @@ class C { void M() { - var builder = ArrayBuilder.[|GetInstance|](); - builder.Add(0); + [|var builder = ArrayBuilder.[|GetInstance|]();|] + [|builder.Add(|]0); Goo(builder.ToImmutableAndClear()); } @@ -1124,7 +1124,7 @@ class C void M() { {{pattern}} - builder.Add(0); + [|builder.Add(|]0); Goo(builder.ToArray()); } @@ -1216,7 +1216,7 @@ ImmutableArray M() {{pattern}} // Leading - builder.Add(0); // Trailing + [|builder.Add(|]0); // Trailing return builder.ToImmutable(); } } @@ -1254,7 +1254,7 @@ class C ImmutableArray M() { {{pattern}} - builder.Add(1 + + [|builder.Add(|]1 + 2); return builder.ToImmutable(); } @@ -1293,9 +1293,9 @@ class C ImmutableArray M() { {{pattern}} - builder.Add(1 + + [|builder.Add(|]1 + 2); - builder.Add(3 + + [|builder.Add(|]3 + 4); return builder.ToImmutable(); } @@ -1355,7 +1355,7 @@ public async Task TestGlobalStatement1(string pattern) using System.Collections.Immutable; {{pattern}} - builder.Add(0); + [|builder.Add(|]0); ImmutableArray array = builder.ToImmutable(); """ + s_arrayBuilderApi, FixedCode = """ @@ -1381,10 +1381,10 @@ public async Task TestGlobalStatement2(string pattern) using System.Collections.Immutable; {{pattern}} - builder.Add(0); - builder.Add(1 + + [|builder.Add(|]0); + [|builder.Add(|]1 + 2); - builder.Add(3 + + [|builder.Add(|]3 + 4); ImmutableArray array = builder.ToImmutable(); """ + s_arrayBuilderApi, @@ -1422,8 +1422,8 @@ class C ImmutableArray> M() { var builder1 = ImmutableArray.CreateBuilder>(); - var builder2 = ImmutableArray.[|CreateBuilder|](); - builder2.Add(0); + [|var builder2 = ImmutableArray.[|CreateBuilder|]();|] + [|builder2.Add(|]0); builder1.Add(builder2.ToImmutable()); return builder1.ToImmutable(); } @@ -1442,7 +1442,6 @@ ImmutableArray> M() """ + s_arrayBuilderApi, LanguageVersion = LanguageVersion.CSharp12, ReferenceAssemblies = ReferenceAssemblies.Net.Net80, - NumberOfIncrementalIterations = 2, NumberOfFixAllIterations = 2, }.RunAsync(); } @@ -1462,8 +1461,8 @@ class C ImmutableArray> M() { var builder1 = ImmutableArray.CreateBuilder>(); - var builder2 = ImmutableArray.[|CreateBuilder|](); - builder2.Add(0); + [|var builder2 = ImmutableArray.[|CreateBuilder|]();|] + [|builder2.Add(|]0); builder1.Add(builder2.ToImmutable()); return builder1.ToImmutable(); } @@ -1482,7 +1481,6 @@ ImmutableArray> M() """ + s_arrayBuilderApi).ReplaceLineEndings(endOfLine), LanguageVersion = LanguageVersion.CSharp12, ReferenceAssemblies = ReferenceAssemblies.Net.Net80, - NumberOfIncrementalIterations = 2, NumberOfFixAllIterations = 2, }.RunAsync(); } diff --git a/src/Analyzers/CSharp/Tests/UseCollectionExpression/UseCollectionExpressionForCreateTests.cs b/src/Analyzers/CSharp/Tests/UseCollectionExpression/UseCollectionExpressionForCreateTests.cs index 6107530c3000b..ee334f8a8b2b6 100644 --- a/src/Analyzers/CSharp/Tests/UseCollectionExpression/UseCollectionExpressionForCreateTests.cs +++ b/src/Analyzers/CSharp/Tests/UseCollectionExpression/UseCollectionExpressionForCreateTests.cs @@ -87,7 +87,7 @@ public async Task TestInCSharp12_Net70() TestCode = """ class C { - MyCollection i = MyCollection.[|Create|](1, 2, 3); + MyCollection i = [|MyCollection.[|Create|](|]1, 2, 3); } """ + s_collectionBuilderApi + s_basicCollectionApi, FixedCode = """ @@ -109,7 +109,7 @@ public async Task TestEmpty() TestCode = """ class C { - MyCollection i = MyCollection.[|Create|](); + MyCollection i = [|MyCollection.[|Create|](|]); } """ + s_collectionBuilderApi + s_basicCollectionApi, FixedCode = """ @@ -133,7 +133,7 @@ class C { void M() { - var i = (MyCollection)MyCollection.[|Create|](); + var i = (MyCollection)[|MyCollection.[|Create|](|]); } } """ + s_collectionBuilderApi + s_basicCollectionApi, @@ -180,7 +180,7 @@ public async Task TestOneElement() TestCode = """ class C { - MyCollection i = MyCollection.[|Create|](1); + MyCollection i = [|MyCollection.[|Create|](|]1); } """ + s_collectionBuilderApi + s_basicCollectionApi, FixedCode = """ @@ -202,7 +202,7 @@ public async Task TestTwoElements() TestCode = """ class C { - MyCollection i = MyCollection.[|Create|](1, 2); + MyCollection i = [|MyCollection.[|Create|](|]1, 2); } """ + s_collectionBuilderApi + s_basicCollectionApi, FixedCode = """ @@ -224,7 +224,7 @@ public async Task TestThreeElements() TestCode = """ class C { - MyCollection i = MyCollection.[|Create|](1, 2, 3); + MyCollection i = [|MyCollection.[|Create|](|]1, 2, 3); } """ + s_collectionBuilderApi + s_basicCollectionApi, FixedCode = """ @@ -246,7 +246,7 @@ public async Task TestFourElements() TestCode = """ class C { - MyCollection i = MyCollection.[|Create|](1, 2, 3, 4); + MyCollection i = [|MyCollection.[|Create|](|]1, 2, 3, 4); } """ + s_collectionBuilderApi + s_basicCollectionApi, FixedCode = """ @@ -268,7 +268,7 @@ public async Task TestParamsWithMultipleElements() TestCode = """ class C { - MyCollection i = MyCollection.[|Create|](1, 2, 3, 4, 5); + MyCollection i = [|MyCollection.[|Create|](|]1, 2, 3, 4, 5); } """ + s_collectionBuilderApi + s_basicCollectionApi, FixedCode = """ @@ -306,7 +306,7 @@ public async Task TestParamsWithExplicitArrayArgument2() TestCode = """ class C { - MyCollection i = MyCollection.[|Create|](new int[] { }); + MyCollection i = [|MyCollection.[|Create|](|]new int[] { }); } """ + s_collectionBuilderApi + s_basicCollectionApi, FixedCode = """ @@ -328,7 +328,7 @@ public async Task TestParamsWithExplicitArrayArgument3() TestCode = """ class C { - MyCollection i = MyCollection.[|Create|](new int[] { 1, 2, 3 }); + MyCollection i = [|MyCollection.[|Create|](|]new int[] { 1, 2, 3 }); } """ + s_collectionBuilderApi + s_basicCollectionApi, FixedCode = """ @@ -350,7 +350,7 @@ public async Task TestParamsWithImplicitArrayArgument1() TestCode = """ class C { - MyCollection i = MyCollection.[|Create|](new[] { 1, 2, 3 }); + MyCollection i = [|MyCollection.[|Create|](|]new[] { 1, 2, 3 }); } """ + s_collectionBuilderApi + s_basicCollectionApi, FixedCode = """ @@ -404,7 +404,7 @@ public async Task TestReadOnlySpan_ExplicitStackAlloc_Net80_1() TestCode = """ class C { - MyCollection i = MyCollection.[|Create|](stackalloc int[] { }); + MyCollection i = [|MyCollection.[|Create|](|]stackalloc int[] { }); } """ + s_collectionBuilderApi + s_basicCollectionApi, FixedCode = """ @@ -426,7 +426,7 @@ public async Task TestReadOnlySpan_ExplicitStackAlloc_Net80_2() TestCode = """ class C { - MyCollection i = MyCollection.[|Create|](stackalloc int[] { 1, 2, 3 }); + MyCollection i = [|MyCollection.[|Create|](|]stackalloc int[] { 1, 2, 3 }); } """ + s_collectionBuilderApi + s_basicCollectionApi, FixedCode = """ @@ -448,7 +448,7 @@ public async Task TestReadOnlySpan_ImplicitStackAlloc_Net80_1() TestCode = """ class C { - MyCollection i = MyCollection.[|Create|](stackalloc[] { 1, 2, 3 }); + MyCollection i = [|MyCollection.[|Create|](|]stackalloc[] { 1, 2, 3 }); } """ + s_collectionBuilderApi + s_basicCollectionApi, FixedCode = """ @@ -523,7 +523,7 @@ public async Task TestCreateRange_ExplicitArray2() TestCode = """ class C { - MyCollection i = MyCollection.[|CreateRange|](new int[] { }); + MyCollection i = [|MyCollection.[|CreateRange|](|]new int[] { }); } """ + s_collectionBuilderApi + s_basicCollectionApi, FixedCode = """ @@ -545,7 +545,7 @@ public async Task TestCreateRange_ExplicitArray3() TestCode = """ class C { - MyCollection i = MyCollection.[|CreateRange|](new int[] { 1, 2, 3 }); + MyCollection i = [|MyCollection.[|CreateRange|](|]new int[] { 1, 2, 3 }); } """ + s_collectionBuilderApi + s_basicCollectionApi, FixedCode = """ @@ -567,7 +567,7 @@ public async Task TestCreateRange_ImplicitArray1() TestCode = """ class C { - MyCollection i = MyCollection.[|CreateRange|](new[] { 1, 2, 3 }); + MyCollection i = [|MyCollection.[|CreateRange|](|]new[] { 1, 2, 3 }); } """ + s_collectionBuilderApi + s_basicCollectionApi, FixedCode = """ @@ -627,7 +627,7 @@ public async Task TestCreateRange_NewObjectWithoutArgument() class C { - MyCollection i = MyCollection.[|CreateRange|](new List()); + MyCollection i = [|MyCollection.[|CreateRange|](|]new List()); } """ + s_collectionBuilderApi + s_basicCollectionApi, FixedCode = """ @@ -653,7 +653,7 @@ public async Task TestCreateRange_NewObjectWithInitializer1() class C { - MyCollection i = MyCollection.[|CreateRange|](new List { }); + MyCollection i = [|MyCollection.[|CreateRange|](|]new List { }); } """ + s_collectionBuilderApi + s_basicCollectionApi, FixedCode = """ @@ -679,7 +679,7 @@ public async Task TestCreateRange_NewObjectWithInitializer2() class C { - MyCollection i = MyCollection.[|CreateRange|](new List() { }); + MyCollection i = [|MyCollection.[|CreateRange|](|]new List() { }); } """ + s_collectionBuilderApi + s_basicCollectionApi, FixedCode = """ @@ -705,7 +705,7 @@ public async Task TestCreateRange_NewObjectWithInitializer3() class C { - MyCollection i = MyCollection.[|CreateRange|](new List { 1, 2, 3 }); + MyCollection i = [|MyCollection.[|CreateRange|](|]new List { 1, 2, 3 }); } """ + s_collectionBuilderApi + s_basicCollectionApi, FixedCode = """ @@ -731,7 +731,7 @@ public async Task TestCreateRange_NewObjectWithInitializer4() class C { - MyCollection i = MyCollection.[|CreateRange|](new List { 1, 2, 3 }); + MyCollection i = [|MyCollection.[|CreateRange|](|]new List { 1, 2, 3 }); } """ + s_collectionBuilderApi + s_basicCollectionApi, FixedCode = """ @@ -792,7 +792,7 @@ public async Task TestTrivia1() TestCode = """ class C { - MyCollection i = /*leading*/ MyCollection.[|Create|](1) /*trailing*/; + MyCollection i = /*leading*/ [|MyCollection.[|Create|](|]1) /*trailing*/; } """ + s_collectionBuilderApi + s_basicCollectionApi, FixedCode = """ @@ -814,7 +814,7 @@ public async Task TestMultiLine1() TestCode = """ class C { - MyCollection i = MyCollection.[|Create|](1 + + MyCollection i = [|MyCollection.[|Create|](|]1 + 2); } """ + s_collectionBuilderApi + s_basicCollectionApi, @@ -838,7 +838,7 @@ public async Task TestMultiLine2() TestCode = """ class C { - MyCollection i = MyCollection.[|Create|](1 + + MyCollection i = [|MyCollection.[|Create|](|]1 + 2, 3 + 4); @@ -896,7 +896,7 @@ class C { void M() { - ImmutableArray v = ImmutableArray.[|Create|](1, 2, 3); + ImmutableArray v = [|ImmutableArray.[|Create|](|]1, 2, 3); } } """, @@ -952,7 +952,7 @@ class C { void M() { - ImmutableList v = ImmutableList.[|Create|](1, 2, 3); + ImmutableList v = [|ImmutableList.[|Create|](|]1, 2, 3); } } """, @@ -979,7 +979,7 @@ public async Task TestGlobalStatement1() await new VerifyCS.Test { TestCode = """ - MyCollection i = MyCollection.[|Create|](); + MyCollection i = [|MyCollection.[|Create|](|]); """ + s_collectionBuilderApi + s_basicCollectionApi, FixedCode = """ MyCollection i = []; @@ -999,7 +999,7 @@ public async Task TestGlobalStatement2() await new VerifyCS.Test { TestCode = """ - MyCollection i = MyCollection.[|Create|](1 + + MyCollection i = [|MyCollection.[|Create|](|]1 + 2, 3 + 4); """ + s_collectionBuilderApi + s_basicCollectionApi, @@ -1034,7 +1034,7 @@ class C { void M() { - ImmutableArray> v = ImmutableArray.[|Create|](ImmutableArray.Create(1, 2, 3)); + ImmutableArray> v = [|ImmutableArray.[|Create|](|]ImmutableArray.Create(1, 2, 3)); } } """, @@ -1052,7 +1052,6 @@ void M() """, LanguageVersion = LanguageVersion.CSharp12, ReferenceAssemblies = ReferenceAssemblies.Net.Net80, - NumberOfIncrementalIterations = 2, NumberOfFixAllIterations = 2, }.RunAsync(); } @@ -1072,7 +1071,7 @@ class C { void M() { - ImmutableArray> v = ImmutableArray.[|Create|](ImmutableArray.Create(1, 2, 3)); + ImmutableArray> v = [|ImmutableArray.[|Create|](|]ImmutableArray.Create(1, 2, 3)); } } """.ReplaceLineEndings(endOfLine), @@ -1090,7 +1089,6 @@ void M() """.ReplaceLineEndings(endOfLine), LanguageVersion = LanguageVersion.CSharp12, ReferenceAssemblies = ReferenceAssemblies.Net.Net80, - NumberOfIncrementalIterations = 2, NumberOfFixAllIterations = 2, }.RunAsync(); } @@ -1111,7 +1109,7 @@ class C { void M() { - Func> f = () => ImmutableArray.[|Create|](1, 2, 3); + Func> f = () => [|ImmutableArray.[|Create|](|]1, 2, 3); } } """, @@ -1198,7 +1196,7 @@ class C { ImmutableArray<(int A, int B)> M() { - return ImmutableArray.[|Create|]((A: 1, 2)); + return [|ImmutableArray.[|Create|](|](A: 1, 2)); } } """, diff --git a/src/Analyzers/CSharp/Tests/UseCollectionExpression/UseCollectionExpressionForStackAllocTests.cs b/src/Analyzers/CSharp/Tests/UseCollectionExpression/UseCollectionExpressionForStackAllocTests.cs index be87d31b23ae4..208437f6edf7c 100644 --- a/src/Analyzers/CSharp/Tests/UseCollectionExpression/UseCollectionExpressionForStackAllocTests.cs +++ b/src/Analyzers/CSharp/Tests/UseCollectionExpression/UseCollectionExpressionForStackAllocTests.cs @@ -115,7 +115,7 @@ class C { void M() { - ReadOnlySpan x = [|stackalloc|] int[] { 1, 2, 3 }; + ReadOnlySpan x = [|[|stackalloc|] int[]|] { 1, 2, 3 }; } } """, @@ -147,7 +147,7 @@ class C { void M() { - ReadOnlySpan x = [|stackalloc|][] { 1, 2, 3 }; + ReadOnlySpan x = [|[|stackalloc|][]|] { 1, 2, 3 }; } } """, @@ -179,7 +179,7 @@ class C { void M() { - Span x = [|stackalloc|] int[] { 1, 2, 3 }; + Span x = [|[|stackalloc|] int[]|] { 1, 2, 3 }; } } """, @@ -211,7 +211,7 @@ class C { void M() { - Span x = [|stackalloc|][] { 1, 2, 3 }; + Span x = [|[|stackalloc|][]|] { 1, 2, 3 }; } } """, @@ -328,7 +328,7 @@ class C void M() { const int size = 1; - ReadOnlySpan x = [|stackalloc|] int[size] { 2 }; + ReadOnlySpan x = [|[|stackalloc|] int[size]|] { 2 }; } } """, @@ -445,7 +445,7 @@ class C { void M() { - Goo([|stackalloc|] int[] { 1, 2, 3 }); + Goo([|[|stackalloc|] int[]|] { 1, 2, 3 }); } void Goo(ReadOnlySpan span) { } @@ -481,7 +481,7 @@ class C { void M() { - Goo([|stackalloc|][] { 1, 2, 3 }); + Goo([|[|stackalloc|][]|] { 1, 2, 3 }); } void Goo(ReadOnlySpan span) { } @@ -517,7 +517,7 @@ class C { void M() { - ReadOnlySpan r = [|stackalloc|] int[] { }; + ReadOnlySpan r = [|[|stackalloc|] int[]|] { }; } } """, @@ -549,7 +549,7 @@ class C { void M() { - var r = (ReadOnlySpan)[|stackalloc|] int[] { }; + var r = (ReadOnlySpan)[|[|stackalloc|] int[]|] { }; } } """, @@ -603,7 +603,7 @@ class C { void M() { - ReadOnlySpan r = [|stackalloc|] int[0] { }; + ReadOnlySpan r = [|[|stackalloc|] int[0]|] { }; } } """, @@ -656,7 +656,7 @@ class C { void M() { - ReadOnlySpan r = [|stackalloc|] int[0]; + ReadOnlySpan r = [|[|stackalloc|] int[0]|]; } } """, @@ -914,7 +914,7 @@ class C { void M(int i, int j) { - Span r = [|stackalloc|] int[1]; + Span r = [|[|stackalloc|] int[1]|]; r[0] = i; } } @@ -947,7 +947,7 @@ class C { void M(int i, int j) { - Span r = [|stackalloc|] int[1]; + Span r = [|[|stackalloc|] int[1]|]; r[0] = i; r[0] = j; } @@ -982,7 +982,7 @@ class C { void M(int i, int j) { - Span r = [|stackalloc|] int[2]; + Span r = [|[|stackalloc|] int[2]|]; r[0] = i; r[1] = j; } @@ -1017,7 +1017,7 @@ class C void M(int i, int j) { const int v = 1; - Span r = [|stackalloc|] int[2]; + Span r = [|[|stackalloc|] int[2]|]; r[0] = i; r[v] = j; } @@ -1125,7 +1125,7 @@ class C { void M(int i, int j) { - Span r = [|stackalloc|] int[2]; + Span r = [|[|stackalloc|] int[2]|]; // Leading r[0] = i; r[1] = j; // Trailing @@ -1165,7 +1165,7 @@ class C { void M(int i, int j) { - Span r = [|stackalloc|] int[2]; + Span r = [|[|stackalloc|] int[2]|]; r[0] = i; // Trailing // Leading r[1] = j; @@ -1205,7 +1205,7 @@ class C { void M(int i, int j) { - Span r = [|stackalloc|] int[] + Span r = [|[|stackalloc|] int[]|] { 1, 2 }; @@ -1243,7 +1243,7 @@ class C { void M(int i, int j) { - Span r = [|stackalloc|] int[] + Span r = [|[|stackalloc|] int[]|] { 1, 2 @@ -1283,7 +1283,7 @@ class C { void M(int i, int j) { - Span r = [|stackalloc|] int[] { + Span r = [|[|stackalloc|] int[]|] { 1, 2 }; } @@ -1319,7 +1319,7 @@ class C { void M(int i, int j) { - Span r = [|stackalloc|] int[] { + Span r = [|[|stackalloc|] int[]|] { 1, 2 }; @@ -1357,7 +1357,7 @@ class C { void M(int i, int j) { - Span r = [|stackalloc|][] + Span r = [|[|stackalloc|][]|] { 1, 2 }; @@ -1395,7 +1395,7 @@ class C { void M(int i, int j) { - Span r = [|stackalloc|][] + Span r = [|[|stackalloc|][]|] { 1, 2 @@ -1435,7 +1435,7 @@ class C { void M(int i, int j) { - Span r = [|stackalloc|][] { + Span r = [|[|stackalloc|][]|] { 1, 2 }; } @@ -1471,7 +1471,7 @@ class C { void M(int i, int j) { - Span r = [|stackalloc|][] { + Span r = [|[|stackalloc|][]|] { 1, 2 }; @@ -1509,7 +1509,7 @@ class C { void M(int i, int j) { - Span r = [|stackalloc|] int[1]; + Span r = [|[|stackalloc|] int[1]|]; r[0] = 1 + 2; } @@ -1547,7 +1547,7 @@ class C { void M(int i, int j) { - Span r = [|stackalloc|] int[2]; + Span r = [|[|stackalloc|] int[2]|]; r[0] = 1 + 2; r[1] = 3 + @@ -1585,7 +1585,7 @@ public async Task TestGlobalStatement1() TestCode = """ using System; - ReadOnlySpan x = [|stackalloc|] int[] { 1, 2, 3 }; + ReadOnlySpan x = [|[|stackalloc|] int[]|] { 1, 2, 3 }; """, FixedCode = """ using System; @@ -1609,7 +1609,7 @@ public async Task TestGlobalStatement2() TestCode = """ using System; - Span r = [|stackalloc|] int[2]; + Span r = [|[|stackalloc|] int[2]|]; r[0] = 1 + 2; r[1] = 3 + diff --git a/src/Analyzers/CSharp/Tests/UseCollectionInitializer/UseCollectionInitializerTests.cs b/src/Analyzers/CSharp/Tests/UseCollectionInitializer/UseCollectionInitializerTests.cs index 45aafdb9245de..e118706ef5eba 100644 --- a/src/Analyzers/CSharp/Tests/UseCollectionInitializer/UseCollectionInitializerTests.cs +++ b/src/Analyzers/CSharp/Tests/UseCollectionInitializer/UseCollectionInitializerTests.cs @@ -65,7 +65,7 @@ class C void M() { var c = [|new|] List(); - c.Add(1); + [|c.Add(|]1); } } """, @@ -125,7 +125,7 @@ class C void M(int[] x) { var c = [|new|] List(); - c.Add(1); + [|c.Add(|]1); c.AddRange(x); } } @@ -159,7 +159,7 @@ class C void M(int[] x) { var c = [|new|] List(); - c.Add(1); + [|c.Add(|]1); foreach (var v in x) c.Add(v); } @@ -195,7 +195,7 @@ class C void M(bool b) { var c = [|new|] List(); - c.Add(1); + [|c.Add(|]1); if (b) c.Add(2); } @@ -231,7 +231,7 @@ class C void M(bool b) { var c = [|new|] List(); - c.Add(1); + [|c.Add(|]1); if (b) c.Add(2); else @@ -271,7 +271,7 @@ class C void M(bool b) { var c = [|new|] List(); - c.Add(1); + [|c.Add(|]1); if (b) { c.Add(2); @@ -527,7 +527,7 @@ class C void M() { var c = [|new|] List(); - c.Add(0); + [|c.Add(|]0); c[1] = 2; } } @@ -560,8 +560,8 @@ class C void M() { var c = [|new|] List(); - c.Add(1); - c.Add(2); + [|c.Add(|]1); + [|c.Add(|]2); throw new System.Exception(); c.Add(3); c.Add(4); @@ -660,7 +660,7 @@ class C void M() { var c = [|new|] List(1); - c.Add(1); + [|c.Add(|]1); } } """, @@ -693,7 +693,7 @@ void M() { List c = null; c = [|new|] List(); - c.Add(1); + [|c.Add(|]1); } } """, @@ -752,8 +752,8 @@ class C void M(List[] array) { array[0] = [|new|] List(); - array[0].Add(1); - array[0].Add(2); + [|array[0].Add(|]1); + [|array[0].Add(|]2); } } """, @@ -807,7 +807,7 @@ void M() { 1 }; - c.Add(1); + [|c.Add(|]1); } } """, @@ -843,7 +843,7 @@ void M() { 1, }; - c.Add(1); + [|c.Add(|]1); } } """, @@ -876,11 +876,11 @@ class C void M(List[] array) { array[0] = [|new|] List(); - array[0].Add(1); - array[0].Add(2); + [|array[0].Add(|]1); + [|array[0].Add(|]2); array[1] = [|new|] List(); - array[1].Add(3); - array[1].Add(4); + [|array[1].Add(|]3); + [|array[1].Add(|]4); } } """, @@ -921,9 +921,9 @@ void M() { var list1 = [|new|] Bar(() => { var list2 = [|new|] List(); - list2.Add(2); + [|list2.Add(|]2); }); - list1.Add(1); + [|list1.Add(|]1); } } @@ -982,9 +982,9 @@ class C void M() { var list1 = [|new|] List(); - list1.Add(() => { + [|list1.Add(|]() => { var list2 = [|new|] List(); - list2.Add(2); + [|list2.Add(|]2); }); } } @@ -1044,8 +1044,8 @@ class C void M() { var c = [|new|] List(); - c.Add(1); // Goo - c.Add(2); // Bar + [|c.Add(|]1); // Goo + [|c.Add(|]2); // Bar } } """, @@ -1079,10 +1079,10 @@ void M() var c = [|new|] List(); // Goo - c.Add(1); + [|c.Add(|]1); // Bar - c.Add(2); + [|c.Add(|]2); } } """, @@ -1117,8 +1117,8 @@ class C void M() { var c = [|new|] Dictionary(); - c.Add(1, "x"); - c.Add(2, "y"); + [|c.Add(|]1, "x"); + [|c.Add(|]2, "y"); } } """, @@ -1154,7 +1154,7 @@ public static void Bar() var items = new List(); var values = [|new|] List(); // Collection initialization can be simplified - values.Add(item); + [|values.Add(|]item); values.AddRange(items); } } @@ -1396,7 +1396,7 @@ public void M() { #if true var items = [|new|] List(); - items.Add(1); + [|items.Add(|]1); #endif } } @@ -1432,7 +1432,7 @@ public void M() { int lastItem; var list = [|new|] List(); - list.Add(lastItem = 5); + [|list.Add(|]lastItem = 5); } } """, @@ -1466,7 +1466,7 @@ public void M() { int lastItem = 0; var list = [|new|] List(); - list.Add(lastItem += 5); + [|list.Add(|]lastItem += 5); } } """, @@ -1499,7 +1499,7 @@ class MyClass public void Main() { var list = [|new|] List(); - list.Add(1); + [|list.Add(|]1); int horse = 1; } @@ -1653,7 +1653,7 @@ await TestInRegularAndScriptAsync( using System.Collections.Generic; var list = [|new|] List(); - list.Add(1); + [|list.Add(|]1); """, """ using System.Collections.Generic; diff --git a/src/Analyzers/CSharp/Tests/UseCollectionInitializer/UseCollectionInitializerTests_CollectionExpression.cs b/src/Analyzers/CSharp/Tests/UseCollectionInitializer/UseCollectionInitializerTests_CollectionExpression.cs index 33dd6a0918e3e..0a160e3d3490a 100644 --- a/src/Analyzers/CSharp/Tests/UseCollectionInitializer/UseCollectionInitializerTests_CollectionExpression.cs +++ b/src/Analyzers/CSharp/Tests/UseCollectionInitializer/UseCollectionInitializerTests_CollectionExpression.cs @@ -48,7 +48,7 @@ class C void M() { var c = [|new|] List(); - c.Add(1); + [|c.Add(|]1); } } """, @@ -97,7 +97,7 @@ class C void M() { var c = [|new|] List(new[] { 1, 2, 3 }); - c.Add(1); + [|c.Add(|]1); } } """, @@ -346,7 +346,7 @@ class C void M() { List c = [|new|] List(); - c.Add(1); + [|c.Add(|]1); } } """, @@ -375,7 +375,7 @@ class C void M(bool b) { List c = [|new|] List(); - c.Add(1); + [|c.Add(|]1); if (b) c.Add(2); } @@ -406,7 +406,7 @@ class C void M(bool b) { List c = [|new|] List(); - c.Add(1); + [|c.Add(|]1); if (b) c.Add(2); else @@ -439,7 +439,7 @@ class C void M(bool b) { List c = [|new|] List(); - c.Add(1); + [|c.Add(|]1); if (b) { c.Add(2); @@ -472,7 +472,7 @@ class C void M(bool b) { List c = [|new|] List(); - c.Add(1); + [|c.Add(|]1); if (b) { c.Add(2); @@ -509,7 +509,7 @@ class C void M(bool b) { List c = [|new|] List(); - c.Add(1); + [|c.Add(|]1); if (b) { c.Add(2); @@ -548,7 +548,7 @@ class C void M(bool b) { List c = [|new|] List(); - c.Add(1); + [|c.Add(|]1); if (b) { c.Add(2); @@ -595,7 +595,7 @@ class C void M(bool b) { List c = [|new|] List(); - c.Add(1); + [|c.Add(|]1); if (b) { } @@ -630,7 +630,7 @@ class C void M(bool b) { List c = [|new|] List(); - c.Add(1); + [|c.Add(|]1); if (b) { c.Add(2); @@ -673,7 +673,7 @@ class C void M() { IList c = [|new|] List(); - c.Add(1); + [|c.Add(|]1); } } """, @@ -705,8 +705,8 @@ class C void M(int[] x) { List c = [|new|] List(); - c.Add(1); - foreach (var v in x) + [|c.Add(|]1); + [|foreach (var v in |]x) c.Add(v); } } @@ -736,8 +736,8 @@ class C void M(int[] x) { List c = [|new|] List(); - c.Add(1); - foreach (var v in x) + [|c.Add(|]1); + [|foreach (var v in |]x) { c.Add(v); } @@ -769,7 +769,7 @@ class C void M(int[] x) { List c = [|new|] List(); - c.Add(1); + [|c.Add(|]1); foreach (var v in x) { c.Add(0); @@ -806,7 +806,7 @@ class C void M(int[] x, int z) { List c = [|new|] List(); - c.Add(1); + [|c.Add(|]1); foreach (var v in x) { c.Add(z); @@ -843,10 +843,10 @@ class C void M(int[] x, int[] y) { List c = [|new|] List(); - c.Add(1); - foreach (var v in x) + [|c.Add(|]1); + [|foreach (var v in |]x) c.Add(v); - foreach (var v in y) + [|foreach (var v in |]y) c.Add(v); } } @@ -876,10 +876,10 @@ class C void M(int[] x, int[] y) { List c = [|new|] List(); - foreach (var v in x) + [|foreach (var v in |]x) c.Add(v); - c.Add(1); - foreach (var v in y) + [|c.Add(|]1); + [|foreach (var v in |]y) c.Add(v); } } @@ -909,11 +909,11 @@ class C void M(int[] x, int[] y) { List c = [|new|] List(); - foreach (var v in x) + [|foreach (var v in |]x) c.Add(v); - foreach (var v in y) + [|foreach (var v in |]y) c.Add(v); - c.Add(1); + [|c.Add(|]1); } } """, @@ -942,7 +942,7 @@ class C async void M(IAsyncEnumerable x) { List c = [|new|] List(); - c.Add(1); + [|c.Add(|]1); await foreach (var v in x) c.Add(v); } @@ -975,8 +975,8 @@ class C void M(int[] x) { List c = [|new|] List(); - c.Add(1); - c.AddRange(x); + [|c.Add(|]1); + [|c.AddRange(|]x); } } """, @@ -1005,10 +1005,10 @@ class C void M(int[] x, int[] y) { List c = [|new|] List(); - c.Add(1); - foreach (var v in x) + [|c.Add(|]1); + [|foreach (var v in |]x) c.Add(v); - c.AddRange(y); + [|c.AddRange(|]y); } } """, @@ -1270,7 +1270,7 @@ class C void M() { List c = [|new|] List(); - c.Add(0); + [|c.Add(|]0); c[1] = 2; } } @@ -1300,8 +1300,8 @@ class C void M() { List c = [|new|] List(); - c.Add(1); - c.Add(2); + [|c.Add(|]1); + [|c.Add(|]2); throw new System.Exception(); c.Add(3); c.Add(4); @@ -1378,7 +1378,7 @@ class C void M() { List c = [|new|] List(1); - c.Add(1); + [|c.Add(|]1); } } """, @@ -1408,7 +1408,7 @@ void M() { List c = null; c = [|new|] List(); - c.Add(1); + [|c.Add(|]1); } } """, @@ -1464,8 +1464,8 @@ class C void M(List[] array) { array[0] = [|new|] List(); - array[0].Add(1); - array[0].Add(2); + [|array[0].Add(|]1); + [|array[0].Add(|]2); } } """, @@ -1527,7 +1527,7 @@ void M() { 1 }; - c.Add(2); + [|c.Add(|]2); } } """, @@ -1562,7 +1562,7 @@ void M() { 1 }; - c.Add(2); + [|c.Add(|]2); } } """, @@ -1597,7 +1597,7 @@ void M() { 1, }; - c.Add(2); + [|c.Add(|]2); } } """, @@ -1632,7 +1632,7 @@ void M(int[] x) { 1 }; - foreach (var y in x) + [|foreach (var y in |]x) c.Add(y); } } @@ -1665,11 +1665,11 @@ class C void M(List[] array) { array[0] = [|new|] List(); - array[0].Add(1); - array[0].Add(2); + [|array[0].Add(|]1); + [|array[0].Add(|]2); array[1] = [|new|] List(); - array[1].Add(3); - array[1].Add(4); + [|array[1].Add(|]3); + [|array[1].Add(|]4); } } """, @@ -1702,9 +1702,9 @@ void M() { Bar list1 = [|new|] Bar(() => { List list2 = [|new|] List(); - list2.Add(2); + [|list2.Add(|]2); }); - list1.Add(1); + [|list1.Add(|]1); } } @@ -1760,9 +1760,9 @@ class C void M() { List list1 = [|new|] List(); - list1.Add(() => { + [|list1.Add(|]() => { List list2 = [|new|] List(); - list2.Add(2); + [|list2.Add(|]2); }); } } @@ -1818,8 +1818,8 @@ class C void M() { List c = [|new|] List(); - c.Add(1); // Goo - c.Add(2); // Bar + [|c.Add(|]1); // Goo + [|c.Add(|]2); // Bar } } """, @@ -1851,11 +1851,11 @@ void M(int[] x, int[] y) { List c = [|new|] List(); // Goo - foreach (var v in x) + [|foreach (var v in |]x) c.Add(v); // Bar - foreach (var v in y) + [|foreach (var v in |]y) c.Add(v); } } @@ -1891,12 +1891,12 @@ void M(int[] x, int[] y) List c = [|new|] List(); // Goo // Bar - foreach (var v in x) + [|foreach (var v in |]x) c.Add(v); // Baz // Quux - foreach (var v in y) + [|foreach (var v in |]y) c.Add(v); } } @@ -2033,10 +2033,10 @@ void M() List c = [|new|] List(); // Goo - c.Add(1); + [|c.Add(|]1); // Bar - c.Add(2); + [|c.Add(|]2); } } """, @@ -2070,8 +2070,8 @@ class C void M() { Dictionary c = [|new|] Dictionary(); - c.Add(1, "x"); - c.Add(2, "y"); + [|c.Add(|]1, "x"); + [|c.Add(|]2, "y"); } } """, @@ -2107,7 +2107,7 @@ public static void Bar() var items = new List(); List values = [|new|] List(); // Collection initialization can be simplified - values.Add(item); + [|values.Add(|]item); values.Remove(item); } } @@ -2385,7 +2385,7 @@ public void M() { #if true List items = [|new|] List(); - items.Add(1); + [|items.Add(|]1); #endif } } @@ -2418,7 +2418,7 @@ public void M() { int lastItem; List list = [|new|] List(); - list.Add(lastItem = 5); + [|list.Add(|]lastItem = 5); } } """, @@ -2449,7 +2449,7 @@ public void M() { int lastItem = 0; List list = [|new|] List(); - list.Add(lastItem += 5); + [|list.Add(|]lastItem += 5); } } """, @@ -2479,7 +2479,7 @@ class MyClass public void Main() { List list = [|new|] List(); - list.Add(1); + [|list.Add(|]1); int horse = 1; } @@ -2630,7 +2630,7 @@ await TestInRegularAndScriptAsync( using System.Collections.Generic; List list = [|new|] List(); - list.Add(1); + [|list.Add(|]1); """, """ using System.Collections.Generic; @@ -3387,7 +3387,7 @@ class C void M() { List c = [|new|] List() { 1, 2 }; - c.Add(3); + [|c.Add(|]3); } } """, @@ -3417,7 +3417,7 @@ void M() { List c = [|new|] List() { 1, 2 }; - c.Add(3); + [|c.Add(|]3); } } """, @@ -3449,7 +3449,7 @@ void M() 1, 2 }; - c.Add(3); + [|c.Add(|]3); } } """, @@ -3483,7 +3483,7 @@ void M() { List c = [|new|] List() { 1, 2 }; - c.Add(3); + [|c.Add(|]3); } } """, @@ -3515,7 +3515,7 @@ void M() List c = [|new|] List() { 1, 2 }; - c.Add(3); + [|c.Add(|]3); } } """, @@ -3550,7 +3550,7 @@ void M() 1, 2, }; - c.Add(3); + [|c.Add(|]3); } } """, @@ -3588,7 +3588,7 @@ void M() 1, 2, }; - c.Add(3); + [|c.Add(|]3); } } """, @@ -3625,7 +3625,7 @@ void M() 1, 2 }; - c.Add(3); + [|c.Add(|]3); } } """, @@ -3661,7 +3661,7 @@ void M() { 1, 2 }; - c.Add(3); + [|c.Add(|]3); } } """, @@ -3696,7 +3696,7 @@ void M() { 1, 2, }; - c.Add(3); + [|c.Add(|]3); } } """, @@ -3728,7 +3728,7 @@ class C void M() { List c = [|new|] List() { 1, 2 }; - c.Add(3 + + [|c.Add(|]3 + 4); } } @@ -3764,7 +3764,7 @@ void M() { List c = [|new|] List() { 1, 2 }; - c.Add(3 + + [|c.Add(|]3 + 4); } } @@ -3802,7 +3802,7 @@ void M() 1, 2 }; - c.Add(3 + + [|c.Add(|]3 + 4); } } @@ -3838,7 +3838,7 @@ void M() { List c = [|new|] List() { 1, 2 }; - c.Add(3 + + [|c.Add(|]3 + 4); } } @@ -3875,7 +3875,7 @@ void M() List c = [|new|] List() { 1, 2 }; - c.Add(3 + + [|c.Add(|]3 + 4); } } @@ -3915,7 +3915,7 @@ void M() 1, 2, }; - c.Add(3 + + [|c.Add(|]3 + 4); } } @@ -3955,7 +3955,7 @@ void M() 1, 2, }; - c.Add(3 + + [|c.Add(|]3 + 4); } } @@ -3994,7 +3994,7 @@ void M() 1, 2 }; - c.Add(3 + + [|c.Add(|]3 + 4); } } @@ -4031,7 +4031,7 @@ void M() List c = [|new|] List() { 1, 2 }; - c.Add(3 + + [|c.Add(|]3 + 4); } } @@ -4067,7 +4067,7 @@ void M() List c = [|new|] List() { 1, 2, }; - c.Add(3 + + [|c.Add(|]3 + 4); } } @@ -4101,7 +4101,7 @@ class C void M() { List c = [|new|] List(); - c.Add(3 + + [|c.Add(|]3 + 4); } } @@ -4135,9 +4135,9 @@ class C void M() { List c = [|new|] List(); - c.Add(1 + + [|c.Add(|]1 + 2); - c.Add(3 + + [|c.Add(|]3 + 4); } } @@ -4283,7 +4283,7 @@ class C void M() { List c = [|new|] List(1); - c.Add(0); + [|c.Add(|]0); } } """, @@ -4312,7 +4312,7 @@ class C void M() { List c = [|new|] List(0); - c.Add(1); + [|c.Add(|]1); } } """, @@ -4344,8 +4344,8 @@ class C void M(int[] x) { List c = [|new|] List(1 + x.Length); - c.Add(0); - c.AddRange(x); + [|c.Add(|]0); + [|c.AddRange(|]x); } } """, @@ -4374,8 +4374,8 @@ class C void M(int[] x) { List c = [|new|] List(x.Length + 1); - c.Add(0); - c.AddRange(x); + [|c.Add(|]0); + [|c.AddRange(|]x); } } """, @@ -4404,9 +4404,9 @@ class C void M(int[] x) { List c = [|new|] List(2 + x.Length); - c.Add(0); - c.AddRange(x); - c.Add(1); + [|c.Add(|]0); + [|c.AddRange(|]x); + [|c.Add(|]1); } } """, @@ -4435,10 +4435,10 @@ class C void M(int[] x, int[] y) { List c = [|new|] List(2 + x.Length + y.Length); - c.Add(0); - c.AddRange(x); - c.AddRange(y); - c.Add(1); + [|c.Add(|]0); + [|c.AddRange(|]x); + [|c.AddRange(|]y); + [|c.Add(|]1); } } """, @@ -4467,10 +4467,10 @@ class C void M(int[] x, int[] y) { List c = [|new|] List(x.Length + y.Length + 2); - c.Add(0); - c.AddRange(x); - c.AddRange(y); - c.Add(1); + [|c.Add(|]0); + [|c.AddRange(|]x); + [|c.AddRange(|]y); + [|c.Add(|]1); } } """, @@ -4499,10 +4499,10 @@ class C void M(int[] x, IList y) { List c = [|new|] List(x.Length + y.Count + 2); - c.Add(0); - c.AddRange(x); - c.AddRange(y); - c.Add(1); + [|c.Add(|]0); + [|c.AddRange(|]x); + [|c.AddRange(|]y); + [|c.Add(|]1); } } """, @@ -4532,10 +4532,10 @@ class C void M(int[] x, IEnumerable y) { List c = [|new|] List(x.Length + y.Count() + 2); - c.Add(0); - c.AddRange(x); - c.AddRange(y); - c.Add(1); + [|c.Add(|]0); + [|c.AddRange(|]x); + [|c.AddRange(|]y); + [|c.Add(|]1); } } """, @@ -4566,8 +4566,8 @@ class C void M(int[] x, IEnumerable y) { List c = [|new|] List(x.Length + y.Count() + 2) { 0, 1 }; - c.AddRange(x); - c.AddRange(y); + [|c.AddRange(|]x); + [|c.AddRange(|]y); } } """, @@ -4597,8 +4597,8 @@ class C void M(int[] x) { List c = [|new|] List(1 + x.Length); - c.Add(1); - foreach (var v in x) + [|c.Add(|]1); + [|foreach (var v in |]x) c.Add(v); } } @@ -4629,10 +4629,10 @@ class C void M(int[] x, IEnumerable y) { List c = [|new|] List(1 + x.Length + y.Count() + 1); - c.Add(0); - c.AddRange(x); - c.AddRange(y); - c.Add(1); + [|c.Add(|]0); + [|c.AddRange(|]x); + [|c.AddRange(|]y); + [|c.Add(|]1); } } """, @@ -4663,7 +4663,7 @@ class C void M(int[] x, IEnumerable y) { List c = [|new|] List(1 + x.Length + y.Count()); - c.Add(0); + [|c.Add(|]0); c.AddRange(x); c.AddRange(y); c.Add(1); @@ -4702,7 +4702,7 @@ class C void M(int[] x, IEnumerable y) { List c = [|new|] List(1 - x.Length); - c.Add(0); + [|c.Add(|]0); c.AddRange(x); } } @@ -4736,7 +4736,7 @@ class C void M(int[] x, IEnumerable y) { List c = [|new|] List(1); - c.Add(0); + [|c.Add(|]0); c.AddRange(x); } } @@ -4770,7 +4770,7 @@ class C void M(int[] x, int[] y) { List c = [|new|] List(1 + x.Length + y.Length); - c.Add(0); + [|c.Add(|]0); c.AddRange(x); } } @@ -4804,7 +4804,7 @@ class C void M(int[] x, int[] y) { List c = [|new|] List(x); - c.Add(0); + [|c.Add(|]0); c.AddRange(y); } } @@ -4839,9 +4839,9 @@ class C void M(int[] x, IEnumerable y) { List c = [|new|] List(x.Length + y.Count() + 2) { 0 }; - c.Add(1); - c.AddRange(x); - c.AddRange(y); + [|c.Add(|]1); + [|c.AddRange(|]x); + [|c.AddRange(|]y); } } """, @@ -4872,7 +4872,7 @@ class C void M(int[] x, IEnumerable y) { List c = [|new|] List(1 + y.Count()); - c.Add(0); + [|c.Add(|]0); c.AddRange(x); } } @@ -4907,10 +4907,10 @@ class C void M(int[] x, IList y) { List c = [|new|] List(x.Length + x.Length + 2); - c.Add(0); - c.AddRange(x); - c.AddRange(x); - c.Add(1); + [|c.Add(|]0); + [|c.AddRange(|]x); + [|c.AddRange(|]x); + [|c.Add(|]1); } } """, @@ -4939,7 +4939,7 @@ class C void M(int[] x, IList y) { List c = [|new|] List(x.Length + 2); - c.Add(0); + [|c.Add(|]0); c.AddRange(x); c.AddRange(x); c.Add(1); @@ -4977,7 +4977,7 @@ class C void M(int[] x, IList y) { List c = [|new|] List(x.Length + x.Length + x.Length + 2); - c.Add(0); + [|c.Add(|]0); c.AddRange(x); c.AddRange(x); c.Add(1); diff --git a/src/Analyzers/Core/Analyzers/UseCollectionInitializer/AbstractUseCollectionInitializerDiagnosticAnalyzer.cs b/src/Analyzers/Core/Analyzers/UseCollectionInitializer/AbstractUseCollectionInitializerDiagnosticAnalyzer.cs index 279e88c541693..c195cfbc27826 100644 --- a/src/Analyzers/Core/Analyzers/UseCollectionInitializer/AbstractUseCollectionInitializerDiagnosticAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/UseCollectionInitializer/AbstractUseCollectionInitializerDiagnosticAnalyzer.cs @@ -10,7 +10,6 @@ using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.LanguageService; using Microsoft.CodeAnalysis.Options; -using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Shared.Collections; using Microsoft.CodeAnalysis.Shared.Extensions; @@ -41,7 +40,7 @@ internal abstract partial class AbstractUseCollectionInitializerDiagnosticAnalyz TLocalDeclarationStatementSyntax, TVariableDeclaratorSyntax, TAnalyzer> - : AbstractBuiltInUnnecessaryCodeStyleDiagnosticAnalyzer + : AbstractBuiltInCodeStyleDiagnosticAnalyzer where TSyntaxKind : struct where TExpressionSyntax : SyntaxNode where TStatementSyntax : SyntaxNode @@ -66,14 +65,26 @@ internal abstract partial class AbstractUseCollectionInitializerDiagnosticAnalyz public override DiagnosticAnalyzerCategory GetAnalyzerCategory() => DiagnosticAnalyzerCategory.SemanticSpanAnalysis; + private static readonly DiagnosticDescriptor s_descriptor = CreateDescriptorWithId( + IDEDiagnosticIds.UseCollectionInitializerDiagnosticId, + EnforceOnBuildValues.UseCollectionInitializer, + hasAnyCodeStyleOption: true, + new LocalizableResourceString(nameof(AnalyzersResources.Simplify_collection_initialization), AnalyzersResources.ResourceManager, typeof(AnalyzersResources)), + new LocalizableResourceString(nameof(AnalyzersResources.Collection_initialization_can_be_simplified), AnalyzersResources.ResourceManager, typeof(AnalyzersResources)), + isUnnecessary: false); + + private static readonly DiagnosticDescriptor s_unnecessaryCodeDescriptor = CreateDescriptorWithId( + IDEDiagnosticIds.UseCollectionInitializerDiagnosticId, + EnforceOnBuildValues.UseCollectionInitializer, + hasAnyCodeStyleOption: true, + new LocalizableResourceString(nameof(AnalyzersResources.Simplify_collection_initialization), AnalyzersResources.ResourceManager, typeof(AnalyzersResources)), + new LocalizableResourceString(nameof(AnalyzersResources.Collection_initialization_can_be_simplified), AnalyzersResources.ResourceManager, typeof(AnalyzersResources)), + isUnnecessary: true); + protected AbstractUseCollectionInitializerDiagnosticAnalyzer() - : base( - IDEDiagnosticIds.UseCollectionInitializerDiagnosticId, - EnforceOnBuildValues.UseCollectionInitializer, - CodeStyleOptions2.PreferCollectionInitializer, - fadingOption: null, - title: new LocalizableResourceString(nameof(AnalyzersResources.Simplify_collection_initialization), AnalyzersResources.ResourceManager, typeof(AnalyzersResources)), - messageFormat: new LocalizableResourceString(nameof(AnalyzersResources.Collection_initialization_can_be_simplified), AnalyzersResources.ResourceManager, typeof(AnalyzersResources))) + : base(ImmutableDictionary.Empty + .Add(s_descriptor, CodeStyleOptions2.PreferCollectionInitializer) + .Add(s_unnecessaryCodeDescriptor, CodeStyleOptions2.PreferCollectionInitializer)) { } @@ -175,20 +186,19 @@ private void AnalyzeNode( if (syntaxFacts.ContainsInterleavedDirective(nodes, cancellationToken)) return; - var location = objectCreationExpression.GetFirstToken().GetLocation(); - var additionalLocations = ImmutableArray.Create(objectCreationExpression.GetLocation()); - var fadingLocations = GetLocationsToFade(matches); + var locations = ImmutableArray.Create(objectCreationExpression.GetLocation()); var option = shouldUseCollectionExpression ? preferExpressionOption : preferInitializerOption; var properties = shouldUseCollectionExpression ? UseCollectionInitializerHelpers.UseCollectionExpressionProperties : null; - context.ReportDiagnostic(DiagnosticHelper.CreateWithLocationTags( - Descriptor, - location, + context.ReportDiagnostic(DiagnosticHelper.Create( + s_descriptor, + objectCreationExpression.GetFirstToken().GetLocation(), option.Notification, - additionalLocations, - fadingLocations, + additionalLocations: locations, properties)); + FadeOutCode(context, matches, locations, properties); + return; (ImmutableArray> matches, bool shouldUseCollectionExpression)? GetCollectionInitializerMatches() @@ -231,19 +241,30 @@ private void AnalyzeNode( } } - private ImmutableArray GetLocationsToFade(ImmutableArray> matches) + private void FadeOutCode( + SyntaxNodeAnalysisContext context, + ImmutableArray> matches, + ImmutableArray locations, + ImmutableDictionary? properties) { var syntaxFacts = this.SyntaxFacts; - using var _ = ArrayBuilder.GetInstance(out var fadingLocations); foreach (var match in matches) { - var locations = UseCollectionInitializerHelpers.GetLocationsToFade( + var additionalUnnecessaryLocations = UseCollectionInitializerHelpers.GetLocationsToFade( syntaxFacts, match); - if (!locations.IsDefaultOrEmpty) - fadingLocations.AddRange(locations); + if (additionalUnnecessaryLocations.IsDefaultOrEmpty) + continue; + + // Report the diagnostic at the first unnecessary location. This is the location where the code fix + // will be offered. + context.ReportDiagnostic(DiagnosticHelper.CreateWithLocationTags( + s_unnecessaryCodeDescriptor, + additionalUnnecessaryLocations[0], + NotificationOption2.ForSeverity(s_unnecessaryCodeDescriptor.DefaultSeverity), + additionalLocations: locations, + additionalUnnecessaryLocations: additionalUnnecessaryLocations, + properties)); } - - return fadingLocations.ToImmutable(); } } diff --git a/src/Analyzers/Core/CodeFixes/UseCoalesceExpression/UseCoalesceExpressionForNullableTernaryConditionalCheckCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/UseCoalesceExpression/UseCoalesceExpressionForNullableTernaryConditionalCheckCodeFixProvider.cs index 6fcbbc9fb0c94..eccfcc0e2598b 100644 --- a/src/Analyzers/Core/CodeFixes/UseCoalesceExpression/UseCoalesceExpressionForNullableTernaryConditionalCheckCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/UseCoalesceExpression/UseCoalesceExpressionForNullableTernaryConditionalCheckCodeFixProvider.cs @@ -25,6 +25,9 @@ internal class UseCoalesceExpressionForNullableTernaryConditionalCheckCodeFixPro public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(IDEDiagnosticIds.UseCoalesceExpressionForNullableTernaryConditionalCheckDiagnosticId); + protected override bool IncludeDiagnosticDuringFixAll(Diagnostic diagnostic) + => !diagnostic.Descriptor.ImmutableCustomTags().Contains(WellKnownDiagnosticTags.Unnecessary); + public override Task RegisterCodeFixesAsync(CodeFixContext context) { RegisterCodeFix(context, AnalyzersResources.Use_coalesce_expression, nameof(AnalyzersResources.Use_coalesce_expression)); diff --git a/src/Analyzers/Core/CodeFixes/UseCoalesceExpression/UseCoalesceExpressionForTernaryConditionalCheckCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/UseCoalesceExpression/UseCoalesceExpressionForTernaryConditionalCheckCodeFixProvider.cs index af549c364208e..21ac3e66d2640 100644 --- a/src/Analyzers/Core/CodeFixes/UseCoalesceExpression/UseCoalesceExpressionForTernaryConditionalCheckCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/UseCoalesceExpression/UseCoalesceExpressionForTernaryConditionalCheckCodeFixProvider.cs @@ -26,6 +26,9 @@ internal class UseCoalesceExpressionForTernaryConditionalCheckCodeFixProvider() public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(IDEDiagnosticIds.UseCoalesceExpressionForTernaryConditionalCheckDiagnosticId); + protected override bool IncludeDiagnosticDuringFixAll(Diagnostic diagnostic) + => !diagnostic.Descriptor.ImmutableCustomTags().Contains(WellKnownDiagnosticTags.Unnecessary); + public override Task RegisterCodeFixesAsync(CodeFixContext context) { RegisterCodeFix(context, AnalyzersResources.Use_coalesce_expression, nameof(AnalyzersResources.Use_coalesce_expression)); diff --git a/src/Analyzers/Core/CodeFixes/UseNullPropagation/AbstractUseNullPropagationCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/UseNullPropagation/AbstractUseNullPropagationCodeFixProvider.cs index ca319faf0ee53..4bb65d0e6fc7e 100644 --- a/src/Analyzers/Core/CodeFixes/UseNullPropagation/AbstractUseNullPropagationCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/UseNullPropagation/AbstractUseNullPropagationCodeFixProvider.cs @@ -56,6 +56,9 @@ internal abstract class AbstractUseNullPropagationCodeFixProvider< public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(IDEDiagnosticIds.UseNullPropagationDiagnosticId); + protected override bool IncludeDiagnosticDuringFixAll(Diagnostic diagnostic) + => !diagnostic.Descriptor.ImmutableCustomTags().Contains(WellKnownDiagnosticTags.Unnecessary); + public override Task RegisterCodeFixesAsync(CodeFixContext context) { RegisterCodeFix(context, AnalyzersResources.Use_null_propagation, nameof(AnalyzersResources.Use_null_propagation)); diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/ForkingSyntaxEditorBasedCodeFixProvider.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/ForkingSyntaxEditorBasedCodeFixProvider.cs index c862967ebcf9b..7efa68191bf83 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/ForkingSyntaxEditorBasedCodeFixProvider.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/ForkingSyntaxEditorBasedCodeFixProvider.cs @@ -51,6 +51,10 @@ protected abstract Task FixAsync( ImmutableDictionary properties, CancellationToken cancellationToken); + protected sealed override bool IncludeDiagnosticDuringFixAll(Diagnostic diagnostic) + // Never try to fix the secondary diagnostics that were produced just to fade out code. + => !diagnostic.Descriptor.ImmutableCustomTags().Contains(WellKnownDiagnosticTags.Unnecessary); + public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) { RegisterCodeFix(context, _title, _equivalenceKey);