From 66a0c7289a925e5311038755498ca4d704b49be2 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 11 Nov 2024 13:39:40 -0800 Subject: [PATCH 1/5] Fix formatting of simplify-linq-expression --- ...rpSimplifyLinqExpressionCodeFixProvider.cs | 5 +- .../Core/Analyzers/Analyzers.projitems | 4 +- .../Core/CodeFixes/CodeFixes.projitems | 2 +- ...ctSimplifyLinqExpressionCodeFixProvider.cs | 62 ++++++++++++++++ ...SimplifyLinqExpressionCodeFixProvider`3.cs | 70 ------------------- ...icSimplifyLinqExpressionCodeFixProvider.vb | 2 - 6 files changed, 67 insertions(+), 78 deletions(-) create mode 100644 src/Analyzers/Core/CodeFixes/SimplifyLinqExpression/AbstractSimplifyLinqExpressionCodeFixProvider.cs delete mode 100644 src/Analyzers/Core/CodeFixes/SimplifyLinqExpression/AbstractSimplifyLinqExpressionCodeFixProvider`3.cs diff --git a/src/Analyzers/CSharp/CodeFixes/SimplifyLinqExpression/CSharpSimplifyLinqExpressionCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/SimplifyLinqExpression/CSharpSimplifyLinqExpressionCodeFixProvider.cs index ea9061d1df6eb..b02bc05901a65 100644 --- a/src/Analyzers/CSharp/CodeFixes/SimplifyLinqExpression/CSharpSimplifyLinqExpressionCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/SimplifyLinqExpression/CSharpSimplifyLinqExpressionCodeFixProvider.cs @@ -15,7 +15,4 @@ namespace Microsoft.CodeAnalysis.CSharp.SimplifyLinqExpression; [ExportCodeFixProvider(LanguageNames.CSharp, Name = PredefinedCodeFixProviderNames.SimplifyLinqExpression), Shared] [method: ImportingConstructor] [method: SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] -internal sealed class CSharpSimplifyLinqExpressionCodeFixProvider() : AbstractSimplifyLinqExpressionCodeFixProvider -{ - protected override ISyntaxFacts SyntaxFacts => CSharpSyntaxFacts.Instance; -} +internal sealed class CSharpSimplifyLinqExpressionCodeFixProvider() : AbstractSimplifyLinqExpressionCodeFixProvider; diff --git a/src/Analyzers/Core/Analyzers/Analyzers.projitems b/src/Analyzers/Core/Analyzers/Analyzers.projitems index ea81bd2ba5653..45e0c4005a393 100644 --- a/src/Analyzers/Core/Analyzers/Analyzers.projitems +++ b/src/Analyzers/Core/Analyzers/Analyzers.projitems @@ -10,7 +10,9 @@ - + + Designer + diff --git a/src/Analyzers/Core/CodeFixes/CodeFixes.projitems b/src/Analyzers/Core/CodeFixes/CodeFixes.projitems index 4bd44bf11c75d..b81658d320787 100644 --- a/src/Analyzers/Core/CodeFixes/CodeFixes.projitems +++ b/src/Analyzers/Core/CodeFixes/CodeFixes.projitems @@ -129,7 +129,7 @@ - + diff --git a/src/Analyzers/Core/CodeFixes/SimplifyLinqExpression/AbstractSimplifyLinqExpressionCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/SimplifyLinqExpression/AbstractSimplifyLinqExpressionCodeFixProvider.cs new file mode 100644 index 0000000000000..ba6b25c251017 --- /dev/null +++ b/src/Analyzers/Core/CodeFixes/SimplifyLinqExpression/AbstractSimplifyLinqExpressionCodeFixProvider.cs @@ -0,0 +1,62 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Immutable; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Editing; +using Microsoft.CodeAnalysis.LanguageService; +using Microsoft.CodeAnalysis.Shared.Extensions; + +namespace Microsoft.CodeAnalysis.SimplifyLinqExpression; + +internal abstract class AbstractSimplifyLinqExpressionCodeFixProvider : SyntaxEditorBasedCodeFixProvider + where TExpressionSyntax : SyntaxNode + where TInvocationExpressionSyntax : TExpressionSyntax + where TSimpleNameSyntax : TExpressionSyntax +{ + public sealed override ImmutableArray FixableDiagnosticIds + => [IDEDiagnosticIds.SimplifyLinqExpressionDiagnosticId]; + + public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) + { + RegisterCodeFix(context, AnalyzersResources.Simplify_LINQ_expression, nameof(AnalyzersResources.Simplify_LINQ_expression)); + return Task.CompletedTask; + } + + protected override Task FixAllAsync( + Document document, + ImmutableArray diagnostics, + SyntaxEditor editor, + CancellationToken cancellationToken) + { + var syntaxFacts = document.GetRequiredLanguageService(); + var root = editor.OriginalRoot; + + foreach (var diagnostic in diagnostics.OrderByDescending(diagnostics => diagnostics.Location.SourceSpan.Start)) + { + var invocation = (TInvocationExpressionSyntax)root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true); + + editor.ReplaceNode(invocation, (current, generator) => + { + var invocation = (TInvocationExpressionSyntax)current; + + var memberAccess = syntaxFacts.GetExpressionOfInvocationExpression(current); + var name = (TSimpleNameSyntax)syntaxFacts.GetNameOfMemberAccessExpression(memberAccess); + var whereExpression = (TInvocationExpressionSyntax)syntaxFacts.GetExpressionOfMemberAccessExpression(memberAccess)!; + var arguments = syntaxFacts.GetArgumentsOfInvocationExpression(whereExpression); + var expression = (TExpressionSyntax)syntaxFacts.GetExpressionOfMemberAccessExpression(syntaxFacts.GetExpressionOfInvocationExpression(whereExpression))!; + + return generator.InvocationExpression( + generator.MemberAccessExpression(expression, name), + arguments).WithTriviaFrom(current); + }); + } + + return Task.CompletedTask; + } +} diff --git a/src/Analyzers/Core/CodeFixes/SimplifyLinqExpression/AbstractSimplifyLinqExpressionCodeFixProvider`3.cs b/src/Analyzers/Core/CodeFixes/SimplifyLinqExpression/AbstractSimplifyLinqExpressionCodeFixProvider`3.cs deleted file mode 100644 index fd404a25cbadf..0000000000000 --- a/src/Analyzers/Core/CodeFixes/SimplifyLinqExpression/AbstractSimplifyLinqExpressionCodeFixProvider`3.cs +++ /dev/null @@ -1,70 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Immutable; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis.CodeActions; -using Microsoft.CodeAnalysis.CodeFixes; -using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.Editing; -using Microsoft.CodeAnalysis.LanguageService; - -namespace Microsoft.CodeAnalysis.SimplifyLinqExpression; - -internal abstract class AbstractSimplifyLinqExpressionCodeFixProvider : SyntaxEditorBasedCodeFixProvider - where TExpressionSyntax : SyntaxNode - where TInvocationExpressionSyntax : TExpressionSyntax - where TSimpleNameSyntax : TExpressionSyntax -{ - protected abstract ISyntaxFacts SyntaxFacts { get; } - - public sealed override ImmutableArray FixableDiagnosticIds - => [IDEDiagnosticIds.SimplifyLinqExpressionDiagnosticId]; - - public override Task RegisterCodeFixesAsync(CodeFixContext context) - { - RegisterCodeFix(context, AnalyzersResources.Simplify_LINQ_expression, nameof(AnalyzersResources.Simplify_LINQ_expression)); - return Task.CompletedTask; - } - - protected override Task FixAllAsync(Document document, - ImmutableArray diagnostics, - SyntaxEditor editor, - CancellationToken cancellationToken) - { - var root = editor.OriginalRoot; - var expressionsToReWrite = diagnostics.Select(d => GetInvocation(root, d)).OrderByDescending(i => i.SpanStart); - foreach (var original in expressionsToReWrite) - { - editor.ReplaceNode(original, (current, generator) => - { - var invocation = (TInvocationExpressionSyntax)current; - var (expression, name, arguments) = FindNodes(invocation); - return generator.InvocationExpression( - generator.MemberAccessExpression(expression, name), - arguments); - }); - } - - return Task.CompletedTask; - - static TInvocationExpressionSyntax GetInvocation(SyntaxNode root, Diagnostic diagnostic) - { - return (TInvocationExpressionSyntax)root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true); - } - - (TExpressionSyntax Expression, TSimpleNameSyntax Name, SeparatedSyntaxList Arguments) FindNodes(TInvocationExpressionSyntax current) - { - var memberAccess = SyntaxFacts.GetExpressionOfInvocationExpression(current); - var name = (TSimpleNameSyntax)SyntaxFacts.GetNameOfMemberAccessExpression(memberAccess); - var whereExpression = (TInvocationExpressionSyntax)SyntaxFacts.GetExpressionOfMemberAccessExpression(memberAccess)!; - var arguments = SyntaxFacts.GetArgumentsOfInvocationExpression(whereExpression); - var expression = (TExpressionSyntax)SyntaxFacts.GetExpressionOfMemberAccessExpression(SyntaxFacts.GetExpressionOfInvocationExpression(whereExpression))!; - return (expression, name, arguments); - } - } -} diff --git a/src/Analyzers/VisualBasic/CodeFixes/SimplifyLinqExpression/VisualBasicSimplifyLinqExpressionCodeFixProvider.vb b/src/Analyzers/VisualBasic/CodeFixes/SimplifyLinqExpression/VisualBasicSimplifyLinqExpressionCodeFixProvider.vb index b2317a224cf4f..161980ac69ebd 100644 --- a/src/Analyzers/VisualBasic/CodeFixes/SimplifyLinqExpression/VisualBasicSimplifyLinqExpressionCodeFixProvider.vb +++ b/src/Analyzers/VisualBasic/CodeFixes/SimplifyLinqExpression/VisualBasicSimplifyLinqExpressionCodeFixProvider.vb @@ -20,7 +20,5 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SimplifyLinqExpression Public Sub New() End Sub - - Protected Overrides ReadOnly Property SyntaxFacts As ISyntaxFacts = VisualBasicSyntaxFacts.Instance End Class End Namespace From af475f1f8352e847efbb2c9c0cbe833a60665818 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 11 Nov 2024 13:45:32 -0800 Subject: [PATCH 2/5] Share fixer --- .../CodeFixes/CSharpCodeFixes.projitems | 1 - ...rpSimplifyLinqExpressionCodeFixProvider.cs | 18 -------------- ...ctSimplifyLinqExpressionCodeFixProvider.cs | 22 ++++++++--------- ...icSimplifyLinqExpressionCodeFixProvider.vb | 24 ------------------- .../CodeFixes/VisualBasicCodeFixes.projitems | 1 - 5 files changed, 11 insertions(+), 55 deletions(-) delete mode 100644 src/Analyzers/CSharp/CodeFixes/SimplifyLinqExpression/CSharpSimplifyLinqExpressionCodeFixProvider.cs delete mode 100644 src/Analyzers/VisualBasic/CodeFixes/SimplifyLinqExpression/VisualBasicSimplifyLinqExpressionCodeFixProvider.vb diff --git a/src/Analyzers/CSharp/CodeFixes/CSharpCodeFixes.projitems b/src/Analyzers/CSharp/CodeFixes/CSharpCodeFixes.projitems index 8eccdc1a5e084..0dcf3b255450c 100644 --- a/src/Analyzers/CSharp/CodeFixes/CSharpCodeFixes.projitems +++ b/src/Analyzers/CSharp/CodeFixes/CSharpCodeFixes.projitems @@ -137,7 +137,6 @@ - diff --git a/src/Analyzers/CSharp/CodeFixes/SimplifyLinqExpression/CSharpSimplifyLinqExpressionCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/SimplifyLinqExpression/CSharpSimplifyLinqExpressionCodeFixProvider.cs deleted file mode 100644 index b02bc05901a65..0000000000000 --- a/src/Analyzers/CSharp/CodeFixes/SimplifyLinqExpression/CSharpSimplifyLinqExpressionCodeFixProvider.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Composition; -using System.Diagnostics.CodeAnalysis; -using Microsoft.CodeAnalysis.CodeFixes; -using Microsoft.CodeAnalysis.CSharp.LanguageService; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.LanguageService; -using Microsoft.CodeAnalysis.SimplifyLinqExpression; - -namespace Microsoft.CodeAnalysis.CSharp.SimplifyLinqExpression; - -[ExportCodeFixProvider(LanguageNames.CSharp, Name = PredefinedCodeFixProviderNames.SimplifyLinqExpression), Shared] -[method: ImportingConstructor] -[method: SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] -internal sealed class CSharpSimplifyLinqExpressionCodeFixProvider() : AbstractSimplifyLinqExpressionCodeFixProvider; diff --git a/src/Analyzers/Core/CodeFixes/SimplifyLinqExpression/AbstractSimplifyLinqExpressionCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/SimplifyLinqExpression/AbstractSimplifyLinqExpressionCodeFixProvider.cs index ba6b25c251017..4de5e98dc5057 100644 --- a/src/Analyzers/Core/CodeFixes/SimplifyLinqExpression/AbstractSimplifyLinqExpressionCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/SimplifyLinqExpression/AbstractSimplifyLinqExpressionCodeFixProvider.cs @@ -3,6 +3,8 @@ // See the LICENSE file in the project root for more information. using System.Collections.Immutable; +using System.Composition; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -14,10 +16,10 @@ namespace Microsoft.CodeAnalysis.SimplifyLinqExpression; -internal abstract class AbstractSimplifyLinqExpressionCodeFixProvider : SyntaxEditorBasedCodeFixProvider - where TExpressionSyntax : SyntaxNode - where TInvocationExpressionSyntax : TExpressionSyntax - where TSimpleNameSyntax : TExpressionSyntax +[ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic, Name = PredefinedCodeFixProviderNames.SimplifyLinqExpression), Shared] +[method: ImportingConstructor] +[method: SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] +internal sealed class SimplifyLinqExpressionCodeFixProvider() : SyntaxEditorBasedCodeFixProvider { public sealed override ImmutableArray FixableDiagnosticIds => [IDEDiagnosticIds.SimplifyLinqExpressionDiagnosticId]; @@ -39,21 +41,19 @@ protected override Task FixAllAsync( foreach (var diagnostic in diagnostics.OrderByDescending(diagnostics => diagnostics.Location.SourceSpan.Start)) { - var invocation = (TInvocationExpressionSyntax)root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true); + var invocation = root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true); editor.ReplaceNode(invocation, (current, generator) => { - var invocation = (TInvocationExpressionSyntax)current; - var memberAccess = syntaxFacts.GetExpressionOfInvocationExpression(current); - var name = (TSimpleNameSyntax)syntaxFacts.GetNameOfMemberAccessExpression(memberAccess); - var whereExpression = (TInvocationExpressionSyntax)syntaxFacts.GetExpressionOfMemberAccessExpression(memberAccess)!; + var name = syntaxFacts.GetNameOfMemberAccessExpression(memberAccess); + var whereExpression = syntaxFacts.GetExpressionOfMemberAccessExpression(memberAccess)!; var arguments = syntaxFacts.GetArgumentsOfInvocationExpression(whereExpression); - var expression = (TExpressionSyntax)syntaxFacts.GetExpressionOfMemberAccessExpression(syntaxFacts.GetExpressionOfInvocationExpression(whereExpression))!; + var expression = syntaxFacts.GetExpressionOfMemberAccessExpression(syntaxFacts.GetExpressionOfInvocationExpression(whereExpression))!; return generator.InvocationExpression( generator.MemberAccessExpression(expression, name), - arguments).WithTriviaFrom(current); + arguments).WithLeadingTrivia(current.GetLeadingTrivia()); }); } diff --git a/src/Analyzers/VisualBasic/CodeFixes/SimplifyLinqExpression/VisualBasicSimplifyLinqExpressionCodeFixProvider.vb b/src/Analyzers/VisualBasic/CodeFixes/SimplifyLinqExpression/VisualBasicSimplifyLinqExpressionCodeFixProvider.vb deleted file mode 100644 index 161980ac69ebd..0000000000000 --- a/src/Analyzers/VisualBasic/CodeFixes/SimplifyLinqExpression/VisualBasicSimplifyLinqExpressionCodeFixProvider.vb +++ /dev/null @@ -1,24 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. -' See the LICENSE file in the project root for more information. - -Imports System.Composition -Imports System.Diagnostics.CodeAnalysis -Imports Microsoft.CodeAnalysis.CodeFixes -Imports Microsoft.CodeAnalysis.LanguageService -Imports Microsoft.CodeAnalysis.SimplifyLinqExpression -Imports Microsoft.CodeAnalysis.VisualBasic.LanguageService -Imports Microsoft.CodeAnalysis.VisualBasic.Syntax - -Namespace Microsoft.CodeAnalysis.VisualBasic.SimplifyLinqExpression - - Friend Class VisualBasicSimplifyLinqExpressionCodeFixProvider - Inherits AbstractSimplifyLinqExpressionCodeFixProvider(Of - InvocationExpressionSyntax, SimpleNameSyntax, ExpressionSyntax) - - - - Public Sub New() - End Sub - End Class -End Namespace diff --git a/src/Analyzers/VisualBasic/CodeFixes/VisualBasicCodeFixes.projitems b/src/Analyzers/VisualBasic/CodeFixes/VisualBasicCodeFixes.projitems index a25a0e527ed83..dcdf21dec4791 100644 --- a/src/Analyzers/VisualBasic/CodeFixes/VisualBasicCodeFixes.projitems +++ b/src/Analyzers/VisualBasic/CodeFixes/VisualBasicCodeFixes.projitems @@ -63,7 +63,6 @@ - From eff1394a84616c321478de1c96122c8e4c32611b Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 11 Nov 2024 13:51:57 -0800 Subject: [PATCH 3/5] Update tests --- ...CSharpSimplifyLinqExpressionFixAllTests.cs | 3 +- .../CSharpSimplifyLinqExpressionTests.cs | 41 ++++++++++++++++++- .../Core/CodeFixes/CodeFixes.projitems | 2 +- ... SimplifyLinqExpressionCodeFixProvider.cs} | 0 ...lBasicSimplifyLinqExpressionFixAllTests.vb | 7 ++-- .../VisualBasicSimplifyLinqExpressionTests.vb | 23 ++++++----- .../BuildActionTelemetryTable/Program.cs | 2 +- 7 files changed, 59 insertions(+), 19 deletions(-) rename src/Analyzers/Core/CodeFixes/SimplifyLinqExpression/{AbstractSimplifyLinqExpressionCodeFixProvider.cs => SimplifyLinqExpressionCodeFixProvider.cs} (100%) diff --git a/src/Analyzers/CSharp/Tests/SimplifyLinqExpression/CSharpSimplifyLinqExpressionFixAllTests.cs b/src/Analyzers/CSharp/Tests/SimplifyLinqExpression/CSharpSimplifyLinqExpressionFixAllTests.cs index 774562e8c2c98..4cd70149a36e7 100644 --- a/src/Analyzers/CSharp/Tests/SimplifyLinqExpression/CSharpSimplifyLinqExpressionFixAllTests.cs +++ b/src/Analyzers/CSharp/Tests/SimplifyLinqExpression/CSharpSimplifyLinqExpressionFixAllTests.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.CSharp.SimplifyLinqExpression; using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; +using Microsoft.CodeAnalysis.SimplifyLinqExpression; using Microsoft.CodeAnalysis.Test.Utilities; using Xunit; @@ -12,7 +13,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Analyzers.UnitTests.SimplifyLinqExpressi using VerifyCS = CSharpCodeFixVerifier< CSharpSimplifyLinqExpressionDiagnosticAnalyzer, - CSharpSimplifyLinqExpressionCodeFixProvider>; + SimplifyLinqExpressionCodeFixProvider>; [Trait(Traits.Feature, Traits.Features.CodeActionsInlineDeclaration)] public partial class CSharpSimplifyLinqExpressionTests diff --git a/src/Analyzers/CSharp/Tests/SimplifyLinqExpression/CSharpSimplifyLinqExpressionTests.cs b/src/Analyzers/CSharp/Tests/SimplifyLinqExpression/CSharpSimplifyLinqExpressionTests.cs index 6e5d611754ff4..fcf08f2b894de 100644 --- a/src/Analyzers/CSharp/Tests/SimplifyLinqExpression/CSharpSimplifyLinqExpressionTests.cs +++ b/src/Analyzers/CSharp/Tests/SimplifyLinqExpression/CSharpSimplifyLinqExpressionTests.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.CSharp.SimplifyLinqExpression; using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; +using Microsoft.CodeAnalysis.SimplifyLinqExpression; using Microsoft.CodeAnalysis.Test.Utilities; using Xunit; @@ -12,10 +13,10 @@ namespace Microsoft.CodeAnalysis.CSharp.Analyzers.UnitTests.SimplifyLinqExpressi using VerifyCS = CSharpCodeFixVerifier< CSharpSimplifyLinqExpressionDiagnosticAnalyzer, - CSharpSimplifyLinqExpressionCodeFixProvider>; + SimplifyLinqExpressionCodeFixProvider>; [Trait(Traits.Feature, Traits.Features.CodeActionsSimplifyLinqExpression)] -public partial class CSharpSimplifyLinqExpressionTests +public sealed partial class CSharpSimplifyLinqExpressionTests { [Theory, CombinatorialData] public static async Task TestAllowedMethodTypes( @@ -525,4 +526,40 @@ void Main() """; await VerifyCS.VerifyAnalyzerAsync(source); } + + [Fact] + public static async Task TestTrivia1() + { + await new VerifyCS.Test + { + TestCode = $$""" + using System; + using System.Linq; + using System.Collections.Generic; + + class C + { + static void Main(string[] args) + { + var v = args.Skip(1) + [|.Where(a => a.Length == 1).Count();|] + } + } + """, + FixedCode = $$""" + using System; + using System.Linq; + using System.Collections.Generic; + + class C + { + static void Main(string[] args) + { + var v = args.Skip(1) + .Count(a => a.Length == 1); + } + } + """ + }.RunAsync(); + } } diff --git a/src/Analyzers/Core/CodeFixes/CodeFixes.projitems b/src/Analyzers/Core/CodeFixes/CodeFixes.projitems index b81658d320787..a2c57739a682d 100644 --- a/src/Analyzers/Core/CodeFixes/CodeFixes.projitems +++ b/src/Analyzers/Core/CodeFixes/CodeFixes.projitems @@ -129,7 +129,7 @@ - + diff --git a/src/Analyzers/Core/CodeFixes/SimplifyLinqExpression/AbstractSimplifyLinqExpressionCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/SimplifyLinqExpression/SimplifyLinqExpressionCodeFixProvider.cs similarity index 100% rename from src/Analyzers/Core/CodeFixes/SimplifyLinqExpression/AbstractSimplifyLinqExpressionCodeFixProvider.cs rename to src/Analyzers/Core/CodeFixes/SimplifyLinqExpression/SimplifyLinqExpressionCodeFixProvider.cs diff --git a/src/Analyzers/VisualBasic/Tests/SimplifyLinqExpression/VisualBasicSimplifyLinqExpressionFixAllTests.vb b/src/Analyzers/VisualBasic/Tests/SimplifyLinqExpression/VisualBasicSimplifyLinqExpressionFixAllTests.vb index 4288e2004cb24..ca5f9856e7799 100644 --- a/src/Analyzers/VisualBasic/Tests/SimplifyLinqExpression/VisualBasicSimplifyLinqExpressionFixAllTests.vb +++ b/src/Analyzers/VisualBasic/Tests/SimplifyLinqExpression/VisualBasicSimplifyLinqExpressionFixAllTests.vb @@ -3,6 +3,7 @@ ' See the LICENSE file in the project root for more information. Imports Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions +Imports Microsoft.CodeAnalysis.SimplifyLinqExpression Namespace Microsoft.CodeAnalysis.VisualBasic.SimplifyLinqExpression @@ -41,7 +42,7 @@ Module T Dim test5 = test.FirstOrDefault(Function(x) x.Equals(""!"")) End Sub End Module" - Await VisualBasicCodeFixVerifier(Of VisualBasicSimplifyLinqExpressionDiagnosticAnalyzer, VisualBasicSimplifyLinqExpressionCodeFixProvider).VerifyCodeFixAsync(testCode, fixedCode) + Await VisualBasicCodeFixVerifier(Of VisualBasicSimplifyLinqExpressionDiagnosticAnalyzer, SimplifyLinqExpressionCodeFixProvider).VerifyCodeFixAsync(testCode, fixedCode) End Function @@ -78,7 +79,7 @@ Module T Dim test5 = Enumerable.FirstOrDefault(test, Function(x) x.Equals(""!"")) End Sub End Module" - Await VisualBasicCodeFixVerifier(Of VisualBasicSimplifyLinqExpressionDiagnosticAnalyzer, VisualBasicSimplifyLinqExpressionCodeFixProvider).VerifyCodeFixAsync(testCode, fixedCode) + Await VisualBasicCodeFixVerifier(Of VisualBasicSimplifyLinqExpressionDiagnosticAnalyzer, SimplifyLinqExpressionCodeFixProvider).VerifyCodeFixAsync(testCode, fixedCode) End Function @@ -115,7 +116,7 @@ Module T Dim test5 = test.FirstOrDefault(Function(x) x.FirstOrDefault(Function(s) s.Equals(""!"")).Equals(""!"")) End Sub End Module" - Await VisualBasicCodeFixVerifier(Of VisualBasicSimplifyLinqExpressionDiagnosticAnalyzer, VisualBasicSimplifyLinqExpressionCodeFixProvider).VerifyCodeFixAsync(testCode, fixedCode) + Await VisualBasicCodeFixVerifier(Of VisualBasicSimplifyLinqExpressionDiagnosticAnalyzer, SimplifyLinqExpressionCodeFixProvider).VerifyCodeFixAsync(testCode, fixedCode) End Function End Class End Namespace diff --git a/src/Analyzers/VisualBasic/Tests/SimplifyLinqExpression/VisualBasicSimplifyLinqExpressionTests.vb b/src/Analyzers/VisualBasic/Tests/SimplifyLinqExpression/VisualBasicSimplifyLinqExpressionTests.vb index 816e9b43d9e25..c4fc3b266cf4a 100644 --- a/src/Analyzers/VisualBasic/Tests/SimplifyLinqExpression/VisualBasicSimplifyLinqExpressionTests.vb +++ b/src/Analyzers/VisualBasic/Tests/SimplifyLinqExpression/VisualBasicSimplifyLinqExpressionTests.vb @@ -3,6 +3,7 @@ ' See the LICENSE file in the project root for more information. Imports Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions +Imports Microsoft.CodeAnalysis.SimplifyLinqExpression Namespace Microsoft.CodeAnalysis.VisualBasic.SimplifyLinqExpression @@ -40,7 +41,7 @@ Module T End Sub End Module" - Await VisualBasicCodeFixVerifier(Of VisualBasicSimplifyLinqExpressionDiagnosticAnalyzer, VisualBasicSimplifyLinqExpressionCodeFixProvider).VerifyCodeFixAsync(testCode, fixedCode) + Await VisualBasicCodeFixVerifier(Of VisualBasicSimplifyLinqExpressionDiagnosticAnalyzer, SimplifyLinqExpressionCodeFixProvider).VerifyCodeFixAsync(testCode, fixedCode) End Function @@ -65,7 +66,7 @@ Module T End Sub End Module" - Await VisualBasicCodeFixVerifier(Of VisualBasicSimplifyLinqExpressionDiagnosticAnalyzer, VisualBasicSimplifyLinqExpressionCodeFixProvider).VerifyAnalyzerAsync(testCode) + Await VisualBasicCodeFixVerifier(Of VisualBasicSimplifyLinqExpressionDiagnosticAnalyzer, SimplifyLinqExpressionCodeFixProvider).VerifyAnalyzerAsync(testCode) End Function @@ -100,7 +101,7 @@ Module T Dim test = (From x In data).{methodName}(Function(x) x = 1) End Sub End Module" - Await VisualBasicCodeFixVerifier(Of VisualBasicSimplifyLinqExpressionDiagnosticAnalyzer, VisualBasicSimplifyLinqExpressionCodeFixProvider).VerifyCodeFixAsync(testCode, fixedCode) + Await VisualBasicCodeFixVerifier(Of VisualBasicSimplifyLinqExpressionDiagnosticAnalyzer, SimplifyLinqExpressionCodeFixProvider).VerifyCodeFixAsync(testCode, fixedCode) End Function @@ -125,7 +126,7 @@ Module T End Sub End Module" - Await VisualBasicCodeFixVerifier(Of VisualBasicSimplifyLinqExpressionDiagnosticAnalyzer, VisualBasicSimplifyLinqExpressionCodeFixProvider).VerifyAnalyzerAsync(testCode) + Await VisualBasicCodeFixVerifier(Of VisualBasicSimplifyLinqExpressionDiagnosticAnalyzer, SimplifyLinqExpressionCodeFixProvider).VerifyAnalyzerAsync(testCode) End Function @@ -166,7 +167,7 @@ Module T End Function) End Sub End Module" - Await VisualBasicCodeFixVerifier(Of VisualBasicSimplifyLinqExpressionDiagnosticAnalyzer, VisualBasicSimplifyLinqExpressionCodeFixProvider).VerifyCodeFixAsync(testCode, fixedCode) + Await VisualBasicCodeFixVerifier(Of VisualBasicSimplifyLinqExpressionDiagnosticAnalyzer, SimplifyLinqExpressionCodeFixProvider).VerifyCodeFixAsync(testCode, fixedCode) End Function @@ -191,7 +192,7 @@ Module T Dim output = testvar2.Where(Function(x) x = 4).{methodName}() End Sub End Module" - Await VisualBasicCodeFixVerifier(Of VisualBasicSimplifyLinqExpressionDiagnosticAnalyzer, VisualBasicSimplifyLinqExpressionCodeFixProvider).VerifyAnalyzerAsync(testCode) + Await VisualBasicCodeFixVerifier(Of VisualBasicSimplifyLinqExpressionDiagnosticAnalyzer, SimplifyLinqExpressionCodeFixProvider).VerifyAnalyzerAsync(testCode) End Function @@ -236,7 +237,7 @@ Module T Dim test1 = test.{firstMethod}(Function(x) x.{secondMethod}(Function(c) c.Equals(""!"")).Equals(""!"")) End Sub End Module" - Await VisualBasicCodeFixVerifier(Of VisualBasicSimplifyLinqExpressionDiagnosticAnalyzer, VisualBasicSimplifyLinqExpressionCodeFixProvider).VerifyCodeFixAsync(testCode, fixedCode) + Await VisualBasicCodeFixVerifier(Of VisualBasicSimplifyLinqExpressionDiagnosticAnalyzer, SimplifyLinqExpressionCodeFixProvider).VerifyCodeFixAsync(testCode, fixedCode) End Function @@ -272,7 +273,7 @@ Module T End Sub End Module" - Await VisualBasicCodeFixVerifier(Of VisualBasicSimplifyLinqExpressionDiagnosticAnalyzer, VisualBasicSimplifyLinqExpressionCodeFixProvider).VerifyCodeFixAsync(testCode, fixedCode) + Await VisualBasicCodeFixVerifier(Of VisualBasicSimplifyLinqExpressionDiagnosticAnalyzer, SimplifyLinqExpressionCodeFixProvider).VerifyCodeFixAsync(testCode, fixedCode) End Function @@ -296,7 +297,7 @@ Module T Dim output = testvar1.Where(Function(x) x = 4).{methodName}(Function(x) x <> 1) End Sub End Module" - Await VisualBasicCodeFixVerifier(Of VisualBasicSimplifyLinqExpressionDiagnosticAnalyzer, VisualBasicSimplifyLinqExpressionCodeFixProvider).VerifyAnalyzerAsync(testCode) + Await VisualBasicCodeFixVerifier(Of VisualBasicSimplifyLinqExpressionDiagnosticAnalyzer, SimplifyLinqExpressionCodeFixProvider).VerifyAnalyzerAsync(testCode) End Function @@ -312,7 +313,7 @@ Module T Dim output = testvar1.Where(Function(x) x = 4).Count() End Sub End Module" - Await VisualBasicCodeFixVerifier(Of VisualBasicSimplifyLinqExpressionDiagnosticAnalyzer, VisualBasicSimplifyLinqExpressionCodeFixProvider).VerifyAnalyzerAsync(testCode) + Await VisualBasicCodeFixVerifier(Of VisualBasicSimplifyLinqExpressionDiagnosticAnalyzer, SimplifyLinqExpressionCodeFixProvider).VerifyAnalyzerAsync(testCode) End Function @@ -341,7 +342,7 @@ Module T Dim result = queryableData.Where(Expression.Lambda(Of Func(Of String, Boolean))(predicateBody, pe)).First() End Sub End Module" - Await VisualBasicCodeFixVerifier(Of VisualBasicSimplifyLinqExpressionDiagnosticAnalyzer, VisualBasicSimplifyLinqExpressionCodeFixProvider).VerifyAnalyzerAsync(testCode) + Await VisualBasicCodeFixVerifier(Of VisualBasicSimplifyLinqExpressionDiagnosticAnalyzer, SimplifyLinqExpressionCodeFixProvider).VerifyAnalyzerAsync(testCode) End Function End Class End Namespace diff --git a/src/Tools/BuildActionTelemetryTable/Program.cs b/src/Tools/BuildActionTelemetryTable/Program.cs index d03b7331e2d4e..e0878467c011b 100644 --- a/src/Tools/BuildActionTelemetryTable/Program.cs +++ b/src/Tools/BuildActionTelemetryTable/Program.cs @@ -402,7 +402,7 @@ public class Program { "Microsoft.CodeAnalysis.VisualBasic.ReplaceConditionalWithStatements.VisualBasicReplaceConditionalWithStatementsCodeRefactoringProvider", "Replace Conditional With Statements (Refactoring)" }, { "Microsoft.CodeAnalysis.VisualBasic.ReplaceDocCommentTextWithTag.VisualBasicReplaceDocCommentTextWithTagCodeRefactoringProvider", "Replace Doc Comment Text With Tag (Refactoring)" }, { "Microsoft.CodeAnalysis.VisualBasic.SimplifyInterpolation.VisualBasicSimplifyInterpolationCodeFixProvider", "Simplify Interpolation" }, - { "Microsoft.CodeAnalysis.VisualBasic.SimplifyLinqExpression.VisualBasicSimplifyLinqExpressionCodeFixProvider", "Simplify Linq Expression" }, + { "Microsoft.CodeAnalysis.VisualBasic.SimplifyLinqExpression.SimplifyLinqExpressionCodeFixProvider", "Simplify Linq Expression" }, { "Microsoft.CodeAnalysis.VisualBasic.SimplifyObjectCreation.VisualBasicSimplifyObjectCreationCodeFixProvider", "Simplify Object Creation" }, { "Microsoft.CodeAnalysis.VisualBasic.SimplifyThisOrMe.VisualBasicSimplifyThisOrMeCodeFixProvider", "Simplify This Or Me" }, { "Microsoft.CodeAnalysis.VisualBasic.SimplifyTypeNames.SimplifyTypeNamesCodeFixProvider", "Simplify Type Names" }, From ad7f251742d094d44ef56813495bc47b630a66af Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 11 Nov 2024 14:09:39 -0800 Subject: [PATCH 4/5] Add test --- .../CSharpSimplifyLinqExpressionTests.cs | 8 +++--- .../SimplifyLinqExpressionCodeFixProvider.cs | 26 +++++++++++++------ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/Analyzers/CSharp/Tests/SimplifyLinqExpression/CSharpSimplifyLinqExpressionTests.cs b/src/Analyzers/CSharp/Tests/SimplifyLinqExpression/CSharpSimplifyLinqExpressionTests.cs index fcf08f2b894de..765f89af739a2 100644 --- a/src/Analyzers/CSharp/Tests/SimplifyLinqExpression/CSharpSimplifyLinqExpressionTests.cs +++ b/src/Analyzers/CSharp/Tests/SimplifyLinqExpression/CSharpSimplifyLinqExpressionTests.cs @@ -532,7 +532,7 @@ public static async Task TestTrivia1() { await new VerifyCS.Test { - TestCode = $$""" + TestCode = """ using System; using System.Linq; using System.Collections.Generic; @@ -541,12 +541,12 @@ class C { static void Main(string[] args) { - var v = args.Skip(1) - [|.Where(a => a.Length == 1).Count();|] + var v = [|args.Skip(1) + .Where(a => a.Length == 1).Count()|]; } } """, - FixedCode = $$""" + FixedCode = """ using System; using System.Linq; using System.Collections.Generic; diff --git a/src/Analyzers/Core/CodeFixes/SimplifyLinqExpression/SimplifyLinqExpressionCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/SimplifyLinqExpression/SimplifyLinqExpressionCodeFixProvider.cs index 4de5e98dc5057..d75e75c4921c7 100644 --- a/src/Analyzers/Core/CodeFixes/SimplifyLinqExpression/SimplifyLinqExpressionCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/SimplifyLinqExpression/SimplifyLinqExpressionCodeFixProvider.cs @@ -45,15 +45,25 @@ protected override Task FixAllAsync( editor.ReplaceNode(invocation, (current, generator) => { + // 'current' is the original full expression. like x.Where(...).Count(); + + // 'x.Where(...).Count' in the above expression var memberAccess = syntaxFacts.GetExpressionOfInvocationExpression(current); - var name = syntaxFacts.GetNameOfMemberAccessExpression(memberAccess); - var whereExpression = syntaxFacts.GetExpressionOfMemberAccessExpression(memberAccess)!; - var arguments = syntaxFacts.GetArgumentsOfInvocationExpression(whereExpression); - var expression = syntaxFacts.GetExpressionOfMemberAccessExpression(syntaxFacts.GetExpressionOfInvocationExpression(whereExpression))!; - - return generator.InvocationExpression( - generator.MemberAccessExpression(expression, name), - arguments).WithLeadingTrivia(current.GetLeadingTrivia()); + + // 'Count' in the above expression + var outerName = syntaxFacts.GetNameOfMemberAccessExpression(memberAccess); + + // 'x.Where(...)' in the above expression. + var innerInvocationExpression = syntaxFacts.GetExpressionOfMemberAccessExpression(memberAccess)!; + + // 'x.Where' in the above expression. + var innerMemberAccessExpression = syntaxFacts.GetExpressionOfInvocationExpression(innerInvocationExpression); + + // 'Where' in the above expression. + var innerName = syntaxFacts.GetNameOfMemberAccessExpression(innerMemberAccessExpression); + + // trim down to the 'x.Where(...)', except with 'Where' replaced with 'Count'. + return innerInvocationExpression.ReplaceNode(innerName, outerName.WithTriviaFrom(innerName)).WithTrailingTrivia(current.GetTrailingTrivia()); }); } From fcaaaf6d5750c3c45a34bc28facb4c23bbe1dea4 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 11 Nov 2024 14:10:29 -0800 Subject: [PATCH 5/5] Work item --- .../CSharpSimplifyLinqExpressionTests.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Analyzers/CSharp/Tests/SimplifyLinqExpression/CSharpSimplifyLinqExpressionTests.cs b/src/Analyzers/CSharp/Tests/SimplifyLinqExpression/CSharpSimplifyLinqExpressionTests.cs index 765f89af739a2..7d340c5d7f1ce 100644 --- a/src/Analyzers/CSharp/Tests/SimplifyLinqExpression/CSharpSimplifyLinqExpressionTests.cs +++ b/src/Analyzers/CSharp/Tests/SimplifyLinqExpression/CSharpSimplifyLinqExpressionTests.cs @@ -7,6 +7,7 @@ using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; using Microsoft.CodeAnalysis.SimplifyLinqExpression; using Microsoft.CodeAnalysis.Test.Utilities; +using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.CSharp.Analyzers.UnitTests.SimplifyLinqExpression; @@ -527,7 +528,7 @@ void Main() await VerifyCS.VerifyAnalyzerAsync(source); } - [Fact] + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52283")] public static async Task TestTrivia1() { await new VerifyCS.Test