From 56a54eaa79359975284c0c7444694b108060cca6 Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Wed, 16 Feb 2022 11:27:12 -0800 Subject: [PATCH 01/31] allow third party codfixers to be run in code cleanup --- .../IDEDiagnosticIdToOptionMappingHelper.cs | 4 ++ .../CodeCleanup/CSharpCodeCleanupService.cs | 4 +- .../VisualBasicCodeCleanupService.vb | 4 +- .../CodeFixes/DiagnosticExtensions.cs | 19 ++++++ .../CodeCleanup/AbstractCodeCleanupService.cs | 65 ++++++++++++++++++- .../CodeCleanup/EnabledDiagnosticOptions.cs | 5 +- .../Features/CodeFixes/CodeFixService.cs | 53 +++++++++++++-- .../Features/CodeFixes/ICodeFixService.cs | 3 + .../CodeCleanup/AbstractCodeCleanUpFixer.cs | 3 + .../CommonCodeCleanUpFixerDiagnosticIds.cs | 9 +++ .../Core/Def/ServicesVSResources.resx | 3 + .../Core/Def/xlf/ServicesVSResources.cs.xlf | 5 ++ .../Core/Def/xlf/ServicesVSResources.de.xlf | 5 ++ .../Core/Def/xlf/ServicesVSResources.es.xlf | 5 ++ .../Core/Def/xlf/ServicesVSResources.fr.xlf | 5 ++ .../Core/Def/xlf/ServicesVSResources.it.xlf | 5 ++ .../Core/Def/xlf/ServicesVSResources.ja.xlf | 5 ++ .../Core/Def/xlf/ServicesVSResources.ko.xlf | 5 ++ .../Core/Def/xlf/ServicesVSResources.pl.xlf | 5 ++ .../Def/xlf/ServicesVSResources.pt-BR.xlf | 5 ++ .../Core/Def/xlf/ServicesVSResources.ru.xlf | 5 ++ .../Core/Def/xlf/ServicesVSResources.tr.xlf | 5 ++ .../Def/xlf/ServicesVSResources.zh-Hans.xlf | 5 ++ .../Def/xlf/ServicesVSResources.zh-Hant.xlf | 5 ++ 24 files changed, 221 insertions(+), 16 deletions(-) create mode 100644 src/Features/Core/Portable/CodeFixes/DiagnosticExtensions.cs diff --git a/src/Analyzers/Core/Analyzers/IDEDiagnosticIdToOptionMappingHelper.cs b/src/Analyzers/Core/Analyzers/IDEDiagnosticIdToOptionMappingHelper.cs index 7d5cf8bebc633..aea5fefc28a35 100644 --- a/src/Analyzers/Core/Analyzers/IDEDiagnosticIdToOptionMappingHelper.cs +++ b/src/Analyzers/Core/Analyzers/IDEDiagnosticIdToOptionMappingHelper.cs @@ -27,6 +27,10 @@ public static bool TryGetMappedOptions(string diagnosticId, string language, [No (s_diagnosticIdToLanguageSpecificOptionsMap.TryGetValue(language, out var map) && map.TryGetValue(diagnosticId, out options)); + public static bool IsKnownIDEDiagnosticId(string diagnosticId) + => s_diagnosticIdToOptionMap.ContainsKey(diagnosticId) || + s_diagnosticIdToLanguageSpecificOptionsMap.Values.Any(map => map.ContainsKey(diagnosticId)); + public static void AddOptionMapping(string diagnosticId, ImmutableHashSet perLanguageOptions) { diagnosticId = diagnosticId ?? throw new ArgumentNullException(nameof(diagnosticId)); diff --git a/src/EditorFeatures/CSharp/CodeCleanup/CSharpCodeCleanupService.cs b/src/EditorFeatures/CSharp/CodeCleanup/CSharpCodeCleanupService.cs index e5fdf3c0feb56..9f9e69f32e1ca 100644 --- a/src/EditorFeatures/CSharp/CodeCleanup/CSharpCodeCleanupService.cs +++ b/src/EditorFeatures/CSharp/CodeCleanup/CSharpCodeCleanupService.cs @@ -267,8 +267,8 @@ internal class CSharpCodeCleanupService : AbstractCodeCleanupService [ImportingConstructor] [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - public CSharpCodeCleanupService(ICodeFixService codeFixService) - : base(codeFixService) + public CSharpCodeCleanupService(ICodeFixService codeFixService, IDiagnosticAnalyzerService diagnosticAnalyzerService) + : base(codeFixService, diagnosticAnalyzerService) { } diff --git a/src/EditorFeatures/VisualBasic/CodeCleanup/VisualBasicCodeCleanupService.vb b/src/EditorFeatures/VisualBasic/CodeCleanup/VisualBasicCodeCleanupService.vb index d4fe3b3949c89..739704a1b50b9 100644 --- a/src/EditorFeatures/VisualBasic/CodeCleanup/VisualBasicCodeCleanupService.vb +++ b/src/EditorFeatures/VisualBasic/CodeCleanup/VisualBasicCodeCleanupService.vb @@ -82,8 +82,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeCleanup - Public Sub New(codeFixService As ICodeFixService) - MyBase.New(codeFixService) + Public Sub New(codeFixService As ICodeFixService, diagnosticAnalyzerService As IDiagnosticAnalyzerService) + MyBase.New(codeFixService, diagnosticAnalyzerService) End Sub Protected Overrides ReadOnly Property OrganizeImportsDescription As String = VBFeaturesResources.Organize_Imports diff --git a/src/Features/Core/Portable/CodeFixes/DiagnosticExtensions.cs b/src/Features/Core/Portable/CodeFixes/DiagnosticExtensions.cs new file mode 100644 index 0000000000000..ae65ba6247759 --- /dev/null +++ b/src/Features/Core/Portable/CodeFixes/DiagnosticExtensions.cs @@ -0,0 +1,19 @@ +// 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 Microsoft.CodeAnalysis.CodeFixes.Suppression; +using Microsoft.CodeAnalysis.Diagnostics; + +namespace Microsoft.CodeAnalysis.CodeFixes +{ + internal static class DiagnosticExtensions + { + public static bool GreaterThanOrEqualTo(this DiagnosticSeverity left, DiagnosticSeverity right) + { + var leftInt = (int)left; + var rightInt = (int)right; + return leftInt >= rightInt; + } + } +} diff --git a/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs b/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs index 910c5c28e0331..13becb1ee782f 100644 --- a/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs +++ b/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs @@ -4,11 +4,13 @@ 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.CodeFixesAndRefactorings; +using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Internal.Log; using Microsoft.CodeAnalysis.OrganizeImports; @@ -16,16 +18,19 @@ using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.Utilities; using Microsoft.CodeAnalysis.Text; +using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CodeCleanup { internal abstract class AbstractCodeCleanupService : ICodeCleanupService { private readonly ICodeFixService _codeFixService; + private readonly IDiagnosticAnalyzerService _diagnosticService; - protected AbstractCodeCleanupService(ICodeFixService codeFixService) + protected AbstractCodeCleanupService(ICodeFixService codeFixService, IDiagnosticAnalyzerService diagnosticAnalyzerService) { _codeFixService = codeFixService; + _diagnosticService = diagnosticAnalyzerService; } protected abstract string OrganizeImportsDescription { get; } @@ -38,7 +43,13 @@ public async Task CleanupAsync( CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) { - // add one item for the 'format' action we'll do last + // add one item for the code fixers we get from nuget, we'll do last + if (enabledDiagnostics.RunThirdPartyFixers) + { + progressTracker.AddItems(1); + } + + // add one item for the 'format' action if (enabledDiagnostics.FormatDocument) { progressTracker.AddItems(1); @@ -76,6 +87,13 @@ public async Task CleanupAsync( } } + if (enabledDiagnostics.RunThirdPartyFixers) + { + document = await ApplyThirdPartyCodeFixesAsync( + document, progressTracker, fallbackOptions, cancellationToken).ConfigureAwait(false); + progressTracker.ItemCompleted(); + } + return document; } @@ -162,7 +180,48 @@ private async Task ApplyCodeFixesForSpecificDiagnosticIdAsync(Document return solution.GetDocument(document.Id) ?? throw new NotSupportedException(FeaturesResources.Removal_of_document_not_supported); } + private async Task ApplyThirdPartyCodeFixesAsync(Document document, IProgressTracker progressTracker, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + { + var tree = await document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); + var range = new TextSpan(0, tree.Length); + + // Compute diagnostics for everything that is not an IDE analyzer + var allDiagnostics = (await _diagnosticService.GetDiagnosticsForSpanAsync(document, range, + shouldIncludeDiagnostic: static diagnosticId => !(IDEDiagnosticIdToOptionMappingHelper.IsKnownIDEDiagnosticId(diagnosticId)), + includeSuppressedDiagnostics: false, + cancellationToken: cancellationToken).ConfigureAwait(false)); + + // ensure more than just compiler diagnostics were returned + var diagnostics = allDiagnostics.WhereAsArray(d => !IsCompilerDiagnostic(d.Id)); + if (!diagnostics.Any()) + { + return document; + } + + foreach (var diagnosticId in diagnostics.SelectAsArray(static d => d.Id).Distinct()) + { + // Apply codefixes for diagnostics with a severity of warning or higher + document = await _codeFixService.ApplyCodeFixesForSpecificDiagnosticIdAsync(document, diagnosticId, DiagnosticSeverity.Warning, progressTracker, fallbackOptions, cancellationToken).ConfigureAwait(false); + } + + return document; + + static bool IsCompilerDiagnostic(string errorId) + { + if (!string.IsNullOrEmpty(errorId) && errorId.Length > 2) + { + var prefix = errorId.Substring(0, 2); + if (prefix.Equals("CS", StringComparison.OrdinalIgnoreCase) || prefix.Equals("BC", StringComparison.OrdinalIgnoreCase)) + { + var suffix = errorId.Substring(2); + return int.TryParse(suffix, out _); + } + } + + return false; + } + } public EnabledDiagnosticOptions GetAllDiagnostics() - => new EnabledDiagnosticOptions(formatDocument: true, GetDiagnosticSets(), new OrganizeUsingsSet(isRemoveUnusedImportEnabled: true, isSortImportsEnabled: true)); + => new EnabledDiagnosticOptions(formatDocument: true, runThirdPartyFixers: true, GetDiagnosticSets(), new OrganizeUsingsSet(isRemoveUnusedImportEnabled: true, isSortImportsEnabled: true)); } } diff --git a/src/Features/LanguageServer/Protocol/Features/CodeCleanup/EnabledDiagnosticOptions.cs b/src/Features/LanguageServer/Protocol/Features/CodeCleanup/EnabledDiagnosticOptions.cs index 7a26f263207d3..7b89ec5b9f87c 100644 --- a/src/Features/LanguageServer/Protocol/Features/CodeCleanup/EnabledDiagnosticOptions.cs +++ b/src/Features/LanguageServer/Protocol/Features/CodeCleanup/EnabledDiagnosticOptions.cs @@ -14,14 +14,15 @@ namespace Microsoft.CodeAnalysis.CodeCleanup internal sealed class EnabledDiagnosticOptions { public bool FormatDocument { get; } - + public bool RunThirdPartyFixers { get; } public ImmutableArray Diagnostics { get; } public OrganizeUsingsSet OrganizeUsings { get; } - public EnabledDiagnosticOptions(bool formatDocument, ImmutableArray diagnostics, OrganizeUsingsSet organizeUsings) + public EnabledDiagnosticOptions(bool formatDocument, bool runThirdPartyFixers, ImmutableArray diagnostics, OrganizeUsingsSet organizeUsings) { FormatDocument = formatDocument; + RunThirdPartyFixers = runThirdPartyFixers; Diagnostics = diagnostics; OrganizeUsings = organizeUsings; } diff --git a/src/Features/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs b/src/Features/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs index 098f4a9f2f30d..aa5c673f0ccb9 100644 --- a/src/Features/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs +++ b/src/Features/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs @@ -230,33 +230,72 @@ private static SortedDictionary> ConvertToMap( return spanToDiagnostics; } - public async Task GetDocumentFixAllForIdInSpanAsync( + public Task GetDocumentFixAllForIdInSpanAsync( Document document, TextSpan range, string diagnosticId, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + => GetDocumentFixAllForIdInSpanAsync(document, range, diagnosticId, DiagnosticSeverity.Hidden, fallbackOptions, cancellationToken); + + public async Task GetDocumentFixAllForIdInSpanAsync( + Document document, TextSpan range, string diagnosticId, DiagnosticSeverity severity, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - var diagnostics = (await _diagnosticService.GetDiagnosticsForSpanAsync(document, range, diagnosticId, includeSuppressedDiagnostics: false, cancellationToken: cancellationToken).ConfigureAwait(false)).ToList(); - if (diagnostics.Count == 0) + var diagnostics = (await _diagnosticService.GetDiagnosticsForSpanAsync(document, range, diagnosticId, includeSuppressedDiagnostics: false, cancellationToken: cancellationToken).ConfigureAwait(false)); + diagnostics = diagnostics.WhereAsArray(d => d.Severity.GreaterThanOrEqualTo(severity)); + if (!diagnostics.Any()) return null; using var resultDisposer = ArrayBuilder.GetInstance(out var result); var spanToDiagnostics = new SortedDictionary> { - { range, diagnostics }, + { range, diagnostics.ToList() }, }; await foreach (var collection in StreamFixesAsync( document, spanToDiagnostics, fixAllForInSpan: true, CodeActionRequestPriority.None, fallbackOptions, isBlocking: false, addOperationScope: static _ => null, cancellationToken).ConfigureAwait(false)) { - // TODO: Just get the first fix for now until we have a way to config user's preferred fix - // https://github.com/dotnet/roslyn/issues/27066 - return collection; + if (collection.FixAllState is not null && collection.SupportedScopes.Contains(FixAllScope.Document)) + { + // TODO: Just get the first fix for now until we have a way to config user's preferred fix + // https://github.com/dotnet/roslyn/issues/27066 + return collection; + } } return null; } + public Task ApplyCodeFixesForSpecificDiagnosticIdAsync(Document document, string diagnosticId, IProgressTracker progressTracker, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + => ApplyCodeFixesForSpecificDiagnosticIdAsync(document, diagnosticId, DiagnosticSeverity.Hidden, progressTracker, fallbackOptions, cancellationToken); + + public async Task ApplyCodeFixesForSpecificDiagnosticIdAsync( + Document document, + string diagnosticId, + DiagnosticSeverity severity, + IProgressTracker progressTracker, + CodeActionOptionsProvider fallbackOptions, + CancellationToken cancellationToken) + { + cancellationToken.ThrowIfCancellationRequested(); + + var tree = await document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); + var textSpan = new TextSpan(0, tree.Length); + + var fixCollection = await GetDocumentFixAllForIdInSpanAsync( + document, textSpan, diagnosticId, severity, fallbackOptions, cancellationToken).ConfigureAwait(false); + if (fixCollection == null) + { + return document; + } + + var fixAllService = document.Project.Solution.Workspace.Services.GetRequiredService(); + + var solution = await fixAllService.GetFixAllChangedSolutionAsync( + new FixAllContext(fixCollection.FixAllState, progressTracker, cancellationToken)).ConfigureAwait(false); + + return solution.GetDocument(document.Id) ?? throw new NotSupportedException(FeaturesResources.Removal_of_document_not_supported); + } + private bool TryGetWorkspaceFixersMap(Document document, [NotNullWhen(true)] out Lazy>>? fixerMap) { if (_lazyWorkspaceFixersMap == null) diff --git a/src/Features/LanguageServer/Protocol/Features/CodeFixes/ICodeFixService.cs b/src/Features/LanguageServer/Protocol/Features/CodeFixes/ICodeFixService.cs index 773cf0a989ddb..e7eba5a38032b 100644 --- a/src/Features/LanguageServer/Protocol/Features/CodeFixes/ICodeFixService.cs +++ b/src/Features/LanguageServer/Protocol/Features/CodeFixes/ICodeFixService.cs @@ -26,6 +26,9 @@ internal interface ICodeFixService Task GetMostSevereFixAsync(Document document, TextSpan range, CodeActionRequestPriority priority, CodeActionOptionsProvider fallbackOptions, bool isBlocking, CancellationToken cancellationToken); Task GetDocumentFixAllForIdInSpanAsync(Document document, TextSpan textSpan, string diagnosticId, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken); + Task GetDocumentFixAllForIdInSpanAsync(Document document, TextSpan textSpan, string diagnosticId, DiagnosticSeverity severity, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken); + Task ApplyCodeFixesForSpecificDiagnosticIdAsync(Document document, string diagnosticId, IProgressTracker progressTracker, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken); + Task ApplyCodeFixesForSpecificDiagnosticIdAsync(Document document, string diagnosticId, DiagnosticSeverity severity, IProgressTracker progressTracker, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken); CodeFixProvider? GetSuppressionFixer(string language, IEnumerable diagnosticIds); } diff --git a/src/VisualStudio/Core/Def/CodeCleanup/AbstractCodeCleanUpFixer.cs b/src/VisualStudio/Core/Def/CodeCleanup/AbstractCodeCleanUpFixer.cs index 30ff5045dd35f..08929ada3b947 100644 --- a/src/VisualStudio/Core/Def/CodeCleanup/AbstractCodeCleanUpFixer.cs +++ b/src/VisualStudio/Core/Def/CodeCleanup/AbstractCodeCleanUpFixer.cs @@ -41,6 +41,7 @@ internal abstract class AbstractCodeCleanUpFixer : ICodeCleanUpFixer protected internal const string FormatDocumentFixId = nameof(FormatDocumentFixId); protected internal const string RemoveUnusedImportsFixId = nameof(RemoveUnusedImportsFixId); protected internal const string SortImportsFixId = nameof(SortImportsFixId); + protected internal const string ApplyThirdPartyFixersId = nameof(ApplyThirdPartyFixersId); private readonly IThreadingContext _threadingContext; private readonly VisualStudioWorkspaceImpl _workspace; @@ -347,8 +348,10 @@ private static async Task FixDocumentAsync( var isFormatDocumentEnabled = enabledFixIds.IsFixIdEnabled(FormatDocumentFixId); var isRemoveUnusedUsingsEnabled = enabledFixIds.IsFixIdEnabled(RemoveUnusedImportsFixId); var isSortUsingsEnabled = enabledFixIds.IsFixIdEnabled(SortImportsFixId); + var isApplyThirdPartyFixersEnabled = enabledFixIds.IsFixIdEnabled(ApplyThirdPartyFixersId); var enabledDiagnostics = new EnabledDiagnosticOptions( isFormatDocumentEnabled, + isApplyThirdPartyFixersEnabled, enabedDiagnosticSets.ToImmutableArray(), new OrganizeUsingsSet(isRemoveUnusedUsingsEnabled, isSortUsingsEnabled)); diff --git a/src/VisualStudio/Core/Def/CodeCleanup/CommonCodeCleanUpFixerDiagnosticIds.cs b/src/VisualStudio/Core/Def/CodeCleanup/CommonCodeCleanUpFixerDiagnosticIds.cs index 4e5fdf2c41488..3fe5fcb9bfa12 100644 --- a/src/VisualStudio/Core/Def/CodeCleanup/CommonCodeCleanUpFixerDiagnosticIds.cs +++ b/src/VisualStudio/Core/Def/CodeCleanup/CommonCodeCleanUpFixerDiagnosticIds.cs @@ -329,5 +329,14 @@ internal static class CommonCodeCleanUpFixerDiagnosticIds [HelpLink($"https://docs.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/{IDEDiagnosticIds.ValueAssignedIsUnusedDiagnosticId}")] [LocalizedName(typeof(FeaturesResources), nameof(FeaturesResources.Apply_unused_value_preferences))] public static readonly FixIdDefinition? ValueAssignedIsUnusedDiagnosticId; + + [Export] + [FixId(AbstractCodeCleanUpFixer.ApplyThirdPartyFixersId)] + [Name(AbstractCodeCleanUpFixer.ApplyThirdPartyFixersId)] + [Order(After = IDEDiagnosticIds.RemoveUnnecessaryCastDiagnosticId)] + [ConfigurationKey("unused")] + [HelpLink($"https://microsoft.com/")] + [LocalizedName(typeof(ServicesVSResources), nameof(ServicesVSResources.Fix_analyzer_warnings_and_errors))] + public static readonly FixIdDefinition? ThirdPartyAnalyzers; } } diff --git a/src/VisualStudio/Core/Def/ServicesVSResources.resx b/src/VisualStudio/Core/Def/ServicesVSResources.resx index 512658dda8c32..dfe9f0a6b9153 100644 --- a/src/VisualStudio/Core/Def/ServicesVSResources.resx +++ b/src/VisualStudio/Core/Def/ServicesVSResources.resx @@ -1971,4 +1971,7 @@ Additional information: {1} Rename asynchronously experimental + + Fix analyzer warnings and errors + \ No newline at end of file diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.cs.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.cs.xlf index 49882ad7eafba..0f6f52c1c8bf9 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.cs.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.cs.xlf @@ -467,6 +467,11 @@ Fix text pasted into string literals (experimental) + + Fix analyzer warnings and errors + Fix analyzer warnings and errors + + For non interface members Pro členy mimo rozhraní diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.de.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.de.xlf index f5ae0c56f6017..fb6b33c61885f 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.de.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.de.xlf @@ -467,6 +467,11 @@ Fix text pasted into string literals (experimental) + + Fix analyzer warnings and errors + Fix analyzer warnings and errors + + For non interface members Für Nichtschnittstellenmember diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.es.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.es.xlf index 2f19705cab247..a5e7b1b2f94a9 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.es.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.es.xlf @@ -467,6 +467,11 @@ Fix text pasted into string literals (experimental) + + Fix analyzer warnings and errors + Fix analyzer warnings and errors + + For non interface members Para miembros que no son de interfaz diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.fr.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.fr.xlf index 1f88b67805949..1b132d56a36a9 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.fr.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.fr.xlf @@ -467,6 +467,11 @@ Fix text pasted into string literals (experimental) + + Fix analyzer warnings and errors + Fix analyzer warnings and errors + + For non interface members Pour les membres non d’interface diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.it.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.it.xlf index b41d35ef75445..5ea13551c6aa9 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.it.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.it.xlf @@ -467,6 +467,11 @@ Fix text pasted into string literals (experimental) + + Fix analyzer warnings and errors + Fix analyzer warnings and errors + + For non interface members Per i membri non di interfaccia diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ja.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ja.xlf index 23ff9c75b6b61..64a264dc15123 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ja.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ja.xlf @@ -467,6 +467,11 @@ Fix text pasted into string literals (experimental) + + Fix analyzer warnings and errors + Fix analyzer warnings and errors + + For non interface members 非インターフェイスメンバーの場合 diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ko.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ko.xlf index 316b5f58b0965..f89bb14bea98a 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ko.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ko.xlf @@ -467,6 +467,11 @@ Fix text pasted into string literals (experimental) + + Fix analyzer warnings and errors + Fix analyzer warnings and errors + + For non interface members 비 인터페이스 멤버의 경우 diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pl.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pl.xlf index 15b5fd76c617a..cfdb25735d7ee 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pl.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pl.xlf @@ -467,6 +467,11 @@ Fix text pasted into string literals (experimental) + + Fix analyzer warnings and errors + Fix analyzer warnings and errors + + For non interface members Dla elementów innych niż składowe interfejsu diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pt-BR.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pt-BR.xlf index 50c1c304c2591..6efb6bac09688 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pt-BR.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pt-BR.xlf @@ -467,6 +467,11 @@ Fix text pasted into string literals (experimental) + + Fix analyzer warnings and errors + Fix analyzer warnings and errors + + For non interface members Para membros sem interface diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ru.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ru.xlf index 6f252fbcc9ba3..bad27900e129e 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ru.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ru.xlf @@ -467,6 +467,11 @@ Fix text pasted into string literals (experimental) + + Fix analyzer warnings and errors + Fix analyzer warnings and errors + + For non interface members Для элементов без интерфейса diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.tr.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.tr.xlf index b428e641109f8..c8ffa2d44c7ef 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.tr.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.tr.xlf @@ -467,6 +467,11 @@ Fix text pasted into string literals (experimental) + + Fix analyzer warnings and errors + Fix analyzer warnings and errors + + For non interface members Arabirim olmayan üyeler için diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hans.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hans.xlf index 9689e5f2474f8..e5c0007bd5a82 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hans.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hans.xlf @@ -467,6 +467,11 @@ Fix text pasted into string literals (experimental) + + Fix analyzer warnings and errors + Fix analyzer warnings and errors + + For non interface members 对于非接口成员 diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hant.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hant.xlf index 5e9fa8c2eada3..e900a4da216c5 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hant.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hant.xlf @@ -467,6 +467,11 @@ Fix text pasted into string literals (experimental) + + Fix analyzer warnings and errors + Fix analyzer warnings and errors + + For non interface members 對於非介面成員 From af0bc75c1389d3d5620974e5a0f0debf620b5ebd Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Tue, 22 Feb 2022 17:22:53 -0800 Subject: [PATCH 02/31] adding tests --- .../Formatting/CodeCleanupTests.TestFixers.cs | 66 +++ .../CSharpTest/Formatting/CodeCleanupTests.cs | 471 +++++++++++++++++- 2 files changed, 536 insertions(+), 1 deletion(-) create mode 100644 src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.TestFixers.cs diff --git a/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.TestFixers.cs b/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.TestFixers.cs new file mode 100644 index 0000000000000..ca6fb4d3d6213 --- /dev/null +++ b/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.TestFixers.cs @@ -0,0 +1,66 @@ +// 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. + +#nullable disable + +using System; +using System.Collections.Immutable; +using System.Composition; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.Host.Mef; + +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Formatting +{ + public partial class CodeCleanupTests + { + private abstract class TestThirdPartyCodeFix : CodeFixProvider + { + public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create("HasDefaultCase"); + + public override Task RegisterCodeFixesAsync(CodeFixContext context) + { + foreach (var diagnostic in context.Diagnostics) + { + context.RegisterCodeFix( + CodeAction.Create( + "Remove default case", + async cancellationToken => + { + var root = await context.Document.GetSyntaxRootAsync(cancellationToken); + var node = (await diagnostic.Location.SourceTree.GetRootAsync(cancellationToken)).FindNode(diagnostic.Location.SourceSpan); + return context.Document.WithSyntaxRoot(root.RemoveNode(node.Parent, SyntaxRemoveOptions.KeepNoTrivia)); + }, + nameof(TestThirdPartyCodeFix)), + diagnostic); + } + + return Task.CompletedTask; + } + } + + [Shared, ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic)] + private class TestThirdPartyCodeFixWithFixAll : TestThirdPartyCodeFix + { + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public TestThirdPartyCodeFixWithFixAll() + { + } + + public override FixAllProvider GetFixAllProvider() => BatchFixAllProvider.Instance; + } + + [Shared, ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic)] + private class TestThirdPartyCodeFixWithOutFixAll : TestThirdPartyCodeFix + { + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public TestThirdPartyCodeFixWithOutFixAll() + { + } + } + } +} diff --git a/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs b/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs index ca55e71dfa792..b296fbb0f0dc8 100644 --- a/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs +++ b/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs @@ -4,6 +4,8 @@ #nullable disable +using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using System.Reflection; using System.Threading; @@ -11,6 +13,7 @@ using Microsoft.CodeAnalysis.AddImport; using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeCleanup; +using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.CodeStyle; using Microsoft.CodeAnalysis.CSharp.CodeStyle; using Microsoft.CodeAnalysis.CSharp.Formatting; @@ -27,13 +30,14 @@ using Microsoft.CodeAnalysis.Simplification; using Microsoft.CodeAnalysis.SolutionCrawler; using Microsoft.CodeAnalysis.Test.Utilities; +using Microsoft.CodeAnalysis.UnitTests.Diagnostics; using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Formatting { [UseExportProvider] - public class CodeCleanupTests + public partial class CodeCleanupTests { [Fact] [Trait(Traits.Feature, Traits.Features.CodeCleanup)] @@ -572,6 +576,471 @@ public void VerifyAllCodeStyleFixersAreSupportedByCodeCleanup(string language, i Assert.Equal(expectedNumberOfUnsupportedDiagnosticIds, unsupportedDiagnosticIds.Length); } + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeCleanup)] + public async Task RunThirdPartyFixerCSharp() + { + const string code = @" +class C +{ + public void M1(int x, int y) + { + switch (x) + { + case 1: + case 10: + break; + default: + break; + } + + switch (y) + { + case 1: + break; + case 1000: + default: + break; + } + + switch (x) + { + case 1: + break; + case 1000: + break; + } + + switch (y) + { + default: + break; + } + + switch (y) { } + + switch (x) + { + case : + case 1000: + break; + } + } +} +"; + + const string expected = @" +class C +{ + public void M1(int x, int y) + { + switch (x) + { + case 1: + case 10: + break; + } + + switch (y) + { + case 1: + break; + } + + switch (x) + { + case 1: + break; + case 1000: + break; + } + + switch (y) + { + } + + switch (y) { } + + switch (x) + { + case : + case 1000: + break; + } + } +} +"; + await TestThirdPartyCodeFixerCSharp(code, expected); + } + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeCleanup)] + public async Task RunThirdPartyFixerVisualBasic() + { + const string code = @" +Class C + Public Sub M1(x As Integer) + Select Case x + Case 1, 2 + Exit Select + Case = 10 + Exit Select + Case Else + Exit Select + End Select + + Select Case x + Case 1 + Exit Select + Case = 1000 + Exit Select + Case Else + Exit Select + End Select + + Select Case x + Case 10 To 500 + Exit Select + Case = 1000 + Exit Select + Case Else + Exit Select + End Select + + Select Case x + Case 1, 980 To 985 + Exit Select + Case Else + Exit Select + End Select + + Select Case x + Case 1 to 3, 980 To 985 + Exit Select + End Select + + Select Case x + Case 1 + Exit Select + Case > 100000 + Exit Select + End Select + + Select Case x + Case Else + Exit Select + End Select + + Select Case x + End Select + + Select Case x + Case 1 + Exit Select + Case + Exit Select + End Select + + Select Case x + Case 1 + Exit Select + Case = + Exit Select + End Select + + Select Case x + Case 1 + Exit Select + Case 2 to + Exit Select + End Select + End Sub +End Class +"; + + const string expected = @" +Class C + Public Sub M1(x As Integer) + Select Case x + Case 1, 2 + Exit Select + Case = 10 + Exit Select + End Select + + Select Case x + Case 1 + Exit Select + Case = 1000 + Exit Select + End Select + + Select Case x + Case 10 To 500 + Exit Select + Case = 1000 + Exit Select + End Select + + Select Case x + Case 1, 980 To 985 + Exit Select + End Select + + Select Case x + Case 1 to 3, 980 To 985 + Exit Select + End Select + + Select Case x + Case 1 + Exit Select + Case > 100000 + Exit Select + End Select + + Select Case x + End Select + + Select Case x + End Select + + Select Case x + Case 1 + Exit Select + Case + Exit Select + End Select + + Select Case x + Case 1 + Exit Select + Case = + Exit Select + End Select + + Select Case x + Case 1 + Exit Select + Case 2 to + Exit Select + End Select + End Sub +End Class +"; + await TestThirdPartyCodeFixerVisualBasic(code, expected); + } + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeCleanup)] + public async Task DoNotRunThirdPartyFixerWithNoFixAllCSharp() + { + const string code = @" +class C +{ + public void M1(int x, int y) + { + switch (x) + { + case 1: + case 10: + break; + default: + break; + } + + switch (y) + { + case 1: + break; + case 1000: + default: + break; + } + + switch (x) + { + case 1: + break; + case 1000: + break; + } + + switch (y) + { + default: + break; + } + + switch (y) { } + + switch (x) + { + case : + case 1000: + break; + } + } +} +"; + + await TestThirdPartyCodeFixerCSharp(code, code); + } + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeCleanup)] + public async Task DoNotRunThirdPartyFixerWithNoFixAllVisualBasic() + { + const string code = @" +Class C + Public Sub M1(x As Integer) + Select Case x + Case 1, 2 + Exit Select + Case = 10 + Exit Select + Case Else + Exit Select + End Select + + Select Case x + Case 1 + Exit Select + Case = 1000 + Exit Select + Case Else + Exit Select + End Select + + Select Case x + Case 10 To 500 + Exit Select + Case = 1000 + Exit Select + Case Else + Exit Select + End Select + + Select Case x + Case 1, 980 To 985 + Exit Select + Case Else + Exit Select + End Select + + Select Case x + Case 1 to 3, 980 To 985 + Exit Select + End Select + + Select Case x + Case 1 + Exit Select + Case > 100000 + Exit Select + End Select + + Select Case x + Case Else + Exit Select + End Select + + Select Case x + End Select + + Select Case x + Case 1 + Exit Select + Case + Exit Select + End Select + + Select Case x + Case 1 + Exit Select + Case = + Exit Select + End Select + + Select Case x + Case 1 + Exit Select + Case 2 to + Exit Select + End Select + End Sub +End Class +"; + + await TestThirdPartyCodeFixerVisualBasic(code, code); + } + + private static Task TestThirdPartyCodeFixerCSharp(string code, string expected) + where TAnalyzer : DiagnosticAnalyzer, new() + where TCodefix : CodeFixProvider, new() + { + return TestThirdPartyCodeFixer(code, expected, LanguageNames.CSharp); + } + + private static Task TestThirdPartyCodeFixerVisualBasic(string code, string expected) + where TAnalyzer : DiagnosticAnalyzer, new() + where TCodefix : CodeFixProvider, new() + { + return TestThirdPartyCodeFixer(code, expected, LanguageNames.VisualBasic); + } + + private static async Task TestThirdPartyCodeFixer(string code, string expected, string language) + where TAnalyzer : DiagnosticAnalyzer, new() + where TCodefix : CodeFixProvider, new() + { + + using var workspace = GetTestWorkspaceForLanguage(code, language); + + var options = CodeActionOptions.Default; + + var project = workspace.CurrentSolution.Projects.Single(); + + var map = new Dictionary>{ + { language, ImmutableArray.Create((DiagnosticAnalyzer)new TAnalyzer()) } + }; + + project = project.AddAnalyzerReference(new TestAnalyzerReferenceByLanguage(map)); + + workspace.TryApplyChanges(project.Solution); + + // register this workspace to solution crawler so that analyzer service associate itself with given workspace + var incrementalAnalyzerProvider = workspace.ExportProvider.GetExportedValue() as IIncrementalAnalyzerProvider; + incrementalAnalyzerProvider.CreateIncrementalAnalyzer(workspace); + + var hostdoc = workspace.Documents.Single(); + var document = workspace.CurrentSolution.GetDocument(hostdoc.Id); + + var codeCleanupService = document.GetLanguageService(); + + var enabledDiagnostics = codeCleanupService.GetAllDiagnostics(); + + var newDoc = await codeCleanupService.CleanupAsync( + document, enabledDiagnostics, new ProgressTracker(), options, CancellationToken.None); + + var actual = await newDoc.GetTextAsync(); + Assert.Equal(expected, actual.ToString()); + + static TestWorkspace GetTestWorkspaceForLanguage(string code, string language) + { + if (language == LanguageNames.CSharp) + { + return TestWorkspace.CreateCSharp(code, composition: EditorTestCompositions.EditorFeaturesWpf.AddParts(typeof(TCodefix))); + } + + if (language == LanguageNames.VisualBasic) + { + return TestWorkspace.CreateVisualBasic(code, composition: EditorTestCompositions.EditorFeaturesWpf.AddParts(typeof(TCodefix))); + } + + return null; + } + } + private static string[] GetSupportedDiagnosticIdsForCodeCleanupService(string language) { using var workspace = GetTestWorkspaceForLanguage(language); From 66c49e21c8d38a39cbe556b1f75cda320304b523 Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Wed, 23 Feb 2022 09:36:24 -0800 Subject: [PATCH 03/31] Update src/Features/Core/Portable/CodeCleanup/AbstractCodeCleanupService.cs Co-authored-by: CyrusNajmabadi --- .../Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs b/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs index 13becb1ee782f..99e4e8af754fb 100644 --- a/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs +++ b/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs @@ -187,7 +187,7 @@ private async Task ApplyThirdPartyCodeFixesAsync(Document document, IP // Compute diagnostics for everything that is not an IDE analyzer var allDiagnostics = (await _diagnosticService.GetDiagnosticsForSpanAsync(document, range, - shouldIncludeDiagnostic: static diagnosticId => !(IDEDiagnosticIdToOptionMappingHelper.IsKnownIDEDiagnosticId(diagnosticId)), + shouldIncludeDiagnostic: static diagnosticId => !IDEDiagnosticIdToOptionMappingHelper.IsKnownIDEDiagnosticId(diagnosticId), includeSuppressedDiagnostics: false, cancellationToken: cancellationToken).ConfigureAwait(false)); From 07715b7455d61be0a5eca77fe08d0ba2f9513dd2 Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Wed, 23 Feb 2022 09:36:31 -0800 Subject: [PATCH 04/31] Update src/Features/Core/Portable/CodeCleanup/AbstractCodeCleanupService.cs Co-authored-by: CyrusNajmabadi --- src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs b/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs index b296fbb0f0dc8..4f7685e004c79 100644 --- a/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs +++ b/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs @@ -996,7 +996,7 @@ private static async Task TestThirdPartyCodeFixer(string co using var workspace = GetTestWorkspaceForLanguage(code, language); - var options = CodeActionOptions.Default; + var options = CodeActionOptions.DefaultProvider; var project = workspace.CurrentSolution.Projects.Single(); From 2a3af87d240c540b57d17556587f6f91c9d6d215 Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Wed, 23 Feb 2022 09:36:41 -0800 Subject: [PATCH 05/31] Update src/Features/Core/Portable/CodeFixes/CodeFixService.cs Co-authored-by: CyrusNajmabadi --- .../Protocol/Features/CodeFixes/CodeFixService.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Features/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs b/src/Features/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs index aa5c673f0ccb9..1030157267357 100644 --- a/src/Features/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs +++ b/src/Features/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs @@ -239,7 +239,8 @@ private static SortedDictionary> ConvertToMap( { cancellationToken.ThrowIfCancellationRequested(); - var diagnostics = (await _diagnosticService.GetDiagnosticsForSpanAsync(document, range, diagnosticId, includeSuppressedDiagnostics: false, cancellationToken: cancellationToken).ConfigureAwait(false)); + var diagnostics = await _diagnosticService.GetDiagnosticsForSpanAsync( + document, range, diagnosticId, includeSuppressedDiagnostics: false, cancellationToken: cancellationToken).ConfigureAwait(false); diagnostics = diagnostics.WhereAsArray(d => d.Severity.GreaterThanOrEqualTo(severity)); if (!diagnostics.Any()) return null; From 51fd8764e67f903e2f2fa30f1244a03f60afe239 Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Wed, 23 Feb 2022 10:40:00 -0800 Subject: [PATCH 06/31] Exports in test code should have [PartNotDiscoverable] applied. --- .../CSharpTest/Formatting/CodeCleanupTests.TestFixers.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.TestFixers.cs b/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.TestFixers.cs index ca6fb4d3d6213..09e72c7a9e3ec 100644 --- a/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.TestFixers.cs +++ b/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.TestFixers.cs @@ -41,7 +41,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) } } - [Shared, ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic)] + [PartNotDiscoverable, Shared, ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic)] private class TestThirdPartyCodeFixWithFixAll : TestThirdPartyCodeFix { [ImportingConstructor] @@ -53,7 +53,7 @@ public TestThirdPartyCodeFixWithFixAll() public override FixAllProvider GetFixAllProvider() => BatchFixAllProvider.Instance; } - [Shared, ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic)] + [PartNotDiscoverable, Shared, ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic)] private class TestThirdPartyCodeFixWithOutFixAll : TestThirdPartyCodeFix { [ImportingConstructor] From 3c2ee92ec3a078f1eb404b85be5eb58d97714f76 Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Wed, 23 Feb 2022 10:40:53 -0800 Subject: [PATCH 07/31] rename severity to minimumSeverity for clarity --- .../Protocol/Features/CodeFixes/CodeFixService.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Features/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs b/src/Features/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs index 1030157267357..754a4d8dd41f5 100644 --- a/src/Features/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs +++ b/src/Features/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs @@ -235,13 +235,13 @@ private static SortedDictionary> ConvertToMap( => GetDocumentFixAllForIdInSpanAsync(document, range, diagnosticId, DiagnosticSeverity.Hidden, fallbackOptions, cancellationToken); public async Task GetDocumentFixAllForIdInSpanAsync( - Document document, TextSpan range, string diagnosticId, DiagnosticSeverity severity, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + Document document, TextSpan range, string diagnosticId, DiagnosticSeverity minimumSeverity, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var diagnostics = await _diagnosticService.GetDiagnosticsForSpanAsync( document, range, diagnosticId, includeSuppressedDiagnostics: false, cancellationToken: cancellationToken).ConfigureAwait(false); - diagnostics = diagnostics.WhereAsArray(d => d.Severity.GreaterThanOrEqualTo(severity)); + diagnostics = diagnostics.WhereAsArray(d => d.Severity.GreaterThanOrEqualTo(minimumSeverity)); if (!diagnostics.Any()) return null; From a75df91cbbf829105d7495402c3b972032660179 Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Wed, 23 Feb 2022 11:30:14 -0800 Subject: [PATCH 08/31] mark mef exported test types as `PartNotDiscoverable` --- .../CSharpTest/Formatting/CodeCleanupTests.TestFixers.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.TestFixers.cs b/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.TestFixers.cs index 09e72c7a9e3ec..c2c496fedf0f2 100644 --- a/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.TestFixers.cs +++ b/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.TestFixers.cs @@ -41,7 +41,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) } } - [PartNotDiscoverable, Shared, ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic)] + [PartNotDiscoverable, Shared, ExportCodeFixProvider(LanguageNames.CSharp)] private class TestThirdPartyCodeFixWithFixAll : TestThirdPartyCodeFix { [ImportingConstructor] @@ -53,7 +53,7 @@ public TestThirdPartyCodeFixWithFixAll() public override FixAllProvider GetFixAllProvider() => BatchFixAllProvider.Instance; } - [PartNotDiscoverable, Shared, ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic)] + [PartNotDiscoverable, Shared, ExportCodeFixProvider(LanguageNames.CSharp)] private class TestThirdPartyCodeFixWithOutFixAll : TestThirdPartyCodeFix { [ImportingConstructor] From 1837a33058e157bdbf44590aca282a2b1a5faa96 Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Wed, 23 Feb 2022 11:30:24 -0800 Subject: [PATCH 09/31] move VB tests to VB test assembly --- .../CSharpTest/Formatting/CodeCleanupTests.cs | 290 +-------------- .../Formatting/CodeCleanUpTests.vb | 331 +++++++++++++++++- 2 files changed, 337 insertions(+), 284 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs b/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs index 4f7685e004c79..345839ca94e21 100644 --- a/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs +++ b/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs @@ -7,7 +7,6 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; -using System.Reflection; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.AddImport; @@ -578,7 +577,7 @@ public void VerifyAllCodeStyleFixersAreSupportedByCodeCleanup(string language, i [Fact] [Trait(Traits.Feature, Traits.Features.CodeCleanup)] - public async Task RunThirdPartyFixerCSharp() + public async Task RunThirdPartyFixer() { const string code = @" class C @@ -670,170 +669,12 @@ public void M1(int x, int y) } } "; - await TestThirdPartyCodeFixerCSharp(code, expected); + await TestThirdPartyCodeFixer(code, expected); } [Fact] [Trait(Traits.Feature, Traits.Features.CodeCleanup)] - public async Task RunThirdPartyFixerVisualBasic() - { - const string code = @" -Class C - Public Sub M1(x As Integer) - Select Case x - Case 1, 2 - Exit Select - Case = 10 - Exit Select - Case Else - Exit Select - End Select - - Select Case x - Case 1 - Exit Select - Case = 1000 - Exit Select - Case Else - Exit Select - End Select - - Select Case x - Case 10 To 500 - Exit Select - Case = 1000 - Exit Select - Case Else - Exit Select - End Select - - Select Case x - Case 1, 980 To 985 - Exit Select - Case Else - Exit Select - End Select - - Select Case x - Case 1 to 3, 980 To 985 - Exit Select - End Select - - Select Case x - Case 1 - Exit Select - Case > 100000 - Exit Select - End Select - - Select Case x - Case Else - Exit Select - End Select - - Select Case x - End Select - - Select Case x - Case 1 - Exit Select - Case - Exit Select - End Select - - Select Case x - Case 1 - Exit Select - Case = - Exit Select - End Select - - Select Case x - Case 1 - Exit Select - Case 2 to - Exit Select - End Select - End Sub -End Class -"; - - const string expected = @" -Class C - Public Sub M1(x As Integer) - Select Case x - Case 1, 2 - Exit Select - Case = 10 - Exit Select - End Select - - Select Case x - Case 1 - Exit Select - Case = 1000 - Exit Select - End Select - - Select Case x - Case 10 To 500 - Exit Select - Case = 1000 - Exit Select - End Select - - Select Case x - Case 1, 980 To 985 - Exit Select - End Select - - Select Case x - Case 1 to 3, 980 To 985 - Exit Select - End Select - - Select Case x - Case 1 - Exit Select - Case > 100000 - Exit Select - End Select - - Select Case x - End Select - - Select Case x - End Select - - Select Case x - Case 1 - Exit Select - Case - Exit Select - End Select - - Select Case x - Case 1 - Exit Select - Case = - Exit Select - End Select - - Select Case x - Case 1 - Exit Select - Case 2 to - Exit Select - End Select - End Sub -End Class -"; - await TestThirdPartyCodeFixerVisualBasic(code, expected); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeCleanup)] - public async Task DoNotRunThirdPartyFixerWithNoFixAllCSharp() + public async Task DoNotRunThirdPartyFixerWithNoFixAll() { const string code = @" class C @@ -884,124 +725,22 @@ public void M1(int x, int y) } "; - await TestThirdPartyCodeFixerCSharp(code, code); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeCleanup)] - public async Task DoNotRunThirdPartyFixerWithNoFixAllVisualBasic() - { - const string code = @" -Class C - Public Sub M1(x As Integer) - Select Case x - Case 1, 2 - Exit Select - Case = 10 - Exit Select - Case Else - Exit Select - End Select - - Select Case x - Case 1 - Exit Select - Case = 1000 - Exit Select - Case Else - Exit Select - End Select - - Select Case x - Case 10 To 500 - Exit Select - Case = 1000 - Exit Select - Case Else - Exit Select - End Select - - Select Case x - Case 1, 980 To 985 - Exit Select - Case Else - Exit Select - End Select - - Select Case x - Case 1 to 3, 980 To 985 - Exit Select - End Select - - Select Case x - Case 1 - Exit Select - Case > 100000 - Exit Select - End Select - - Select Case x - Case Else - Exit Select - End Select - - Select Case x - End Select - - Select Case x - Case 1 - Exit Select - Case - Exit Select - End Select - - Select Case x - Case 1 - Exit Select - Case = - Exit Select - End Select - - Select Case x - Case 1 - Exit Select - Case 2 to - Exit Select - End Select - End Sub -End Class -"; - - await TestThirdPartyCodeFixerVisualBasic(code, code); - } - - private static Task TestThirdPartyCodeFixerCSharp(string code, string expected) - where TAnalyzer : DiagnosticAnalyzer, new() - where TCodefix : CodeFixProvider, new() - { - return TestThirdPartyCodeFixer(code, expected, LanguageNames.CSharp); - } - - private static Task TestThirdPartyCodeFixerVisualBasic(string code, string expected) - where TAnalyzer : DiagnosticAnalyzer, new() - where TCodefix : CodeFixProvider, new() - { - return TestThirdPartyCodeFixer(code, expected, LanguageNames.VisualBasic); + await TestThirdPartyCodeFixer(code, code); } - private static async Task TestThirdPartyCodeFixer(string code, string expected, string language) + private static async Task TestThirdPartyCodeFixer(string code, string expected) where TAnalyzer : DiagnosticAnalyzer, new() where TCodefix : CodeFixProvider, new() { - using var workspace = GetTestWorkspaceForLanguage(code, language); + using var workspace = TestWorkspace.CreateCSharp(code, composition: EditorTestCompositions.EditorFeaturesWpf.AddParts(typeof(TCodefix))); var options = CodeActionOptions.DefaultProvider; var project = workspace.CurrentSolution.Projects.Single(); var map = new Dictionary>{ - { language, ImmutableArray.Create((DiagnosticAnalyzer)new TAnalyzer()) } + { LanguageNames.CSharp, ImmutableArray.Create((DiagnosticAnalyzer)new TAnalyzer()) } }; project = project.AddAnalyzerReference(new TestAnalyzerReferenceByLanguage(map)); @@ -1024,21 +763,6 @@ private static async Task TestThirdPartyCodeFixer(string co var actual = await newDoc.GetTextAsync(); Assert.Equal(expected, actual.ToString()); - - static TestWorkspace GetTestWorkspaceForLanguage(string code, string language) - { - if (language == LanguageNames.CSharp) - { - return TestWorkspace.CreateCSharp(code, composition: EditorTestCompositions.EditorFeaturesWpf.AddParts(typeof(TCodefix))); - } - - if (language == LanguageNames.VisualBasic) - { - return TestWorkspace.CreateVisualBasic(code, composition: EditorTestCompositions.EditorFeaturesWpf.AddParts(typeof(TCodefix))); - } - - return null; - } } private static string[] GetSupportedDiagnosticIdsForCodeCleanupService(string language) diff --git a/src/EditorFeatures/VisualBasicTest/Formatting/CodeCleanUpTests.vb b/src/EditorFeatures/VisualBasicTest/Formatting/CodeCleanUpTests.vb index 1e57fc9d05efa..0c4cf3c55e6b3 100644 --- a/src/EditorFeatures/VisualBasicTest/Formatting/CodeCleanUpTests.vb +++ b/src/EditorFeatures/VisualBasicTest/Formatting/CodeCleanUpTests.vb @@ -2,29 +2,34 @@ ' 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.Collections.Immutable +Imports System.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.AddImport Imports Microsoft.CodeAnalysis.CodeActions Imports Microsoft.CodeAnalysis.CodeCleanup Imports Microsoft.CodeAnalysis.CodeGeneration +Imports Microsoft.CodeAnalysis.CodeFixes Imports Microsoft.CodeAnalysis.Diagnostics Imports Microsoft.CodeAnalysis.Diagnostics.VisualBasic Imports Microsoft.CodeAnalysis.Editing Imports Microsoft.CodeAnalysis.Editor.UnitTests Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces Imports Microsoft.CodeAnalysis.Formatting +Imports Microsoft.CodeAnalysis.Host.Mef Imports Microsoft.CodeAnalysis.MakeFieldReadonly Imports Microsoft.CodeAnalysis.Options Imports Microsoft.CodeAnalysis.Shared.Utilities Imports Microsoft.CodeAnalysis.SolutionCrawler Imports Microsoft.CodeAnalysis.VisualBasic.CodeGeneration +Imports Microsoft.CodeAnalysis.UnitTests.Diagnostics Imports Microsoft.CodeAnalysis.VisualBasic.Diagnostics.Analyzers Imports Microsoft.CodeAnalysis.VisualBasic.Formatting Imports Microsoft.CodeAnalysis.VisualBasic.Simplification Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Formatting - Public Class CodeCleanUpTests + Partial Public Class CodeCleanUpTests ' Format Document tests are handled by Format Document Test ' TESTS NEEDED but not found in C# @@ -323,6 +328,283 @@ End Class Return AssertCodeCleanupResultAsync(expected, code) End Function + + + Public Shared Async Function RunThirdPartyFixer() As Task + Dim code As String = " +Class C + Public Sub M1(x As Integer) + Select Case x + Case 1, 2 + Exit Select + Case = 10 + Exit Select + Case Else + Exit Select + End Select + + Select Case x + Case 1 + Exit Select + Case = 1000 + Exit Select + Case Else + Exit Select + End Select + + Select Case x + Case 10 To 500 + Exit Select + Case = 1000 + Exit Select + Case Else + Exit Select + End Select + + Select Case x + Case 1, 980 To 985 + Exit Select + Case Else + Exit Select + End Select + + Select Case x + Case 1 to 3, 980 To 985 + Exit Select + End Select + + Select Case x + Case 1 + Exit Select + Case > 100000 + Exit Select + End Select + + Select Case x + Case Else + Exit Select + End Select + + Select Case x + End Select + + Select Case x + Case 1 + Exit Select + Case + Exit Select + End Select + + Select Case x + Case 1 + Exit Select + Case = + Exit Select + End Select + + Select Case x + Case 1 + Exit Select + Case 2 to + Exit Select + End Select + End Sub +End Class +" + Dim expected As String = " +Class C + Public Sub M1(x As Integer) + Select Case x + Case 1, 2 + Exit Select + Case = 10 + Exit Select + End Select + + Select Case x + Case 1 + Exit Select + Case = 1000 + Exit Select + End Select + + Select Case x + Case 10 To 500 + Exit Select + Case = 1000 + Exit Select + End Select + + Select Case x + Case 1, 980 To 985 + Exit Select + End Select + + Select Case x + Case 1 to 3, 980 To 985 + Exit Select + End Select + + Select Case x + Case 1 + Exit Select + Case > 100000 + Exit Select + End Select + + Select Case x + End Select + + Select Case x + End Select + + Select Case x + Case 1 + Exit Select + Case + Exit Select + End Select + + Select Case x + Case 1 + Exit Select + Case = + Exit Select + End Select + + Select Case x + Case 1 + Exit Select + Case 2 to + Exit Select + End Select + End Sub +End Class +" + Await TestThirdPartyCodeFixer(Of TestThirdPartyCodeFixWithFixAll, CaseTestAnalyzer)(expected, code) + End Function + + + + Public Shared Async Function DoNotRunThirdPartyFixerWithNoFixAll() As Task + Dim code As String = " +Class C + Public Sub M1(x As Integer) + Select Case x + Case 1, 2 + Exit Select + Case = 10 + Exit Select + Case Else + Exit Select + End Select + + Select Case x + Case 1 + Exit Select + Case = 1000 + Exit Select + Case Else + Exit Select + End Select + + Select Case x + Case 10 To 500 + Exit Select + Case = 1000 + Exit Select + Case Else + Exit Select + End Select + + Select Case x + Case 1, 980 To 985 + Exit Select + Case Else + Exit Select + End Select + + Select Case x + Case 1 to 3, 980 To 985 + Exit Select + End Select + + Select Case x + Case 1 + Exit Select + Case > 100000 + Exit Select + End Select + + Select Case x + Case Else + Exit Select + End Select + + Select Case x + End Select + + Select Case x + Case 1 + Exit Select + Case + Exit Select + End Select + + Select Case x + Case 1 + Exit Select + Case = + Exit Select + End Select + + Select Case x + Case 1 + Exit Select + Case 2 to + Exit Select + End Select + End Sub +End Class +" + Await TestThirdPartyCodeFixer(Of TestThirdPartyCodeFixWithOutFixAll, CaseTestAnalyzer)(code, code) + End Function + + Private Shared Async Function TestThirdPartyCodeFixer(Of TCodefix As {CodeFixProvider, New}, TAnalyzer As {DiagnosticAnalyzer, New})(expected As String, code As String) As Task + Using workspace = TestWorkspace.CreateVisualBasic(code, composition:=EditorTestCompositions.EditorFeaturesWpf.AddParts(GetType(TCodefix))) + Dim options = CodeActionOptions.DefaultProvider + Dim project = workspace.CurrentSolution.Projects.Single() + Dim map = New Dictionary(Of String, ImmutableArray(Of DiagnosticAnalyzer)) From + { + {LanguageNames.VisualBasic, ImmutableArray.Create(Of DiagnosticAnalyzer)(New TAnalyzer())} + } + project = project.AddAnalyzerReference(New TestAnalyzerReferenceByLanguage(map)) + workspace.TryApplyChanges(project.Solution) + + ' register this workspace to solution crawler so that analyzer service associate itself with given workspace + Dim incrementalAnalyzerProvider = TryCast(workspace.ExportProvider.GetExportedValue(Of IDiagnosticAnalyzerService)(), IIncrementalAnalyzerProvider) + incrementalAnalyzerProvider.CreateIncrementalAnalyzer(workspace) + + Dim hostdoc = workspace.Documents.[Single]() + Dim document = workspace.CurrentSolution.GetDocument(hostdoc.Id) + + Dim codeCleanupService = document.GetLanguageService(Of ICodeCleanupService)() + + Dim enabledDiagnostics = codeCleanupService.GetAllDiagnostics() + + Dim newDoc = Await codeCleanupService.CleanupAsync( + document, + enabledDiagnostics, + New ProgressTracker, + options, + CancellationToken.None) + + Dim actual = Await newDoc.GetTextAsync() + + AssertEx.EqualOrDiff(expected, actual.ToString()) + End Using + End Function + ''' ''' Assert the expected code value equals the actual processed input . ''' @@ -375,5 +657,52 @@ End Class End Using End Function + + Private Class TestThirdPartyCodeFixWithFixAll : Inherits TestThirdPartyCodeFix + + + + Public Sub New() + End Sub + + Public Overrides Function GetFixAllProvider() As FixAllProvider + Return BatchFixAllProvider.Instance + End Function + End Class + + + Private Class TestThirdPartyCodeFixWithOutFixAll : Inherits TestThirdPartyCodeFix + + + + Public Sub New() + End Sub + End Class + + Private Class TestThirdPartyCodeFix : Inherits CodeFixProvider + + Public Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) + Get + Return ImmutableArray.Create("HasDefaultCase") + End Get + End Property + + Public Overrides Function RegisterCodeFixesAsync(context As CodeFixContext) As Task + For Each diagnostic In context.Diagnostics + context.RegisterCodeFix( + CodeAction.Create( + "Remove default case", + Async Function(cancellationToken) + Dim root = Await context.Document.GetSyntaxRootAsync(cancellationToken) + Dim node = (Await diagnostic.Location.SourceTree.GetRootAsync(cancellationToken)).FindNode(diagnostic.Location.SourceSpan) + Return context.Document.WithSyntaxRoot(root.RemoveNode(node.Parent, SyntaxRemoveOptions.KeepNoTrivia)) + End Function, + NameOf(TestThirdPartyCodeFix)), + diagnostic) + Next + + Return Task.CompletedTask + End Function + End Class End Class End Namespace From e5966afcc60a2b0da58d2482056531308fc911d8 Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Wed, 23 Feb 2022 11:38:15 -0800 Subject: [PATCH 10/31] move old members to extension method --- .../Protocol/Features/CodeFixes/ICodeFixService.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Features/LanguageServer/Protocol/Features/CodeFixes/ICodeFixService.cs b/src/Features/LanguageServer/Protocol/Features/CodeFixes/ICodeFixService.cs index e7eba5a38032b..88a4cb254fc08 100644 --- a/src/Features/LanguageServer/Protocol/Features/CodeFixes/ICodeFixService.cs +++ b/src/Features/LanguageServer/Protocol/Features/CodeFixes/ICodeFixService.cs @@ -25,9 +25,7 @@ internal interface ICodeFixService /// Task GetMostSevereFixAsync(Document document, TextSpan range, CodeActionRequestPriority priority, CodeActionOptionsProvider fallbackOptions, bool isBlocking, CancellationToken cancellationToken); - Task GetDocumentFixAllForIdInSpanAsync(Document document, TextSpan textSpan, string diagnosticId, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken); Task GetDocumentFixAllForIdInSpanAsync(Document document, TextSpan textSpan, string diagnosticId, DiagnosticSeverity severity, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken); - Task ApplyCodeFixesForSpecificDiagnosticIdAsync(Document document, string diagnosticId, IProgressTracker progressTracker, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken); Task ApplyCodeFixesForSpecificDiagnosticIdAsync(Document document, string diagnosticId, DiagnosticSeverity severity, IProgressTracker progressTracker, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken); CodeFixProvider? GetSuppressionFixer(string language, IEnumerable diagnosticIds); } @@ -42,5 +40,11 @@ public static Task> GetFixesAsync(this ICodeFi public static Task> GetFixesAsync(this ICodeFixService service, Document document, TextSpan textSpan, CodeActionRequestPriority priority, CodeActionOptionsProvider fallbackOptions, bool isBlocking, Func addOperationScope, CancellationToken cancellationToken) => service.StreamFixesAsync(document, textSpan, priority, fallbackOptions, isBlocking, addOperationScope, cancellationToken).ToImmutableArrayAsync(cancellationToken); + + public static Task GetDocumentFixAllForIdInSpanAsync(this ICodeFixService service, Document document, TextSpan range, string diagnosticId, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + => service.GetDocumentFixAllForIdInSpanAsync(document, range, diagnosticId, DiagnosticSeverity.Hidden, fallbackOptions, cancellationToken); + + public static Task ApplyCodeFixesForSpecificDiagnosticIdAsync(this ICodeFixService service, Document document, string diagnosticId, IProgressTracker progressTracker, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + => service.ApplyCodeFixesForSpecificDiagnosticIdAsync(document, diagnosticId, DiagnosticSeverity.Hidden, progressTracker, fallbackOptions, cancellationToken); } } From 32bcffa49636095a87a738f841b899c10de5b69a Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Wed, 23 Feb 2022 11:41:51 -0800 Subject: [PATCH 11/31] filter compiler diagnostics in Diagnostic Service call --- .../Features/CodeCleanup/AbstractCodeCleanupService.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs b/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs index 99e4e8af754fb..cf275f6f5e031 100644 --- a/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs +++ b/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs @@ -186,13 +186,12 @@ private async Task ApplyThirdPartyCodeFixesAsync(Document document, IP var range = new TextSpan(0, tree.Length); // Compute diagnostics for everything that is not an IDE analyzer - var allDiagnostics = (await _diagnosticService.GetDiagnosticsForSpanAsync(document, range, - shouldIncludeDiagnostic: static diagnosticId => !IDEDiagnosticIdToOptionMappingHelper.IsKnownIDEDiagnosticId(diagnosticId), + var diagnostics = (await _diagnosticService.GetDiagnosticsForSpanAsync(document, range, + shouldIncludeDiagnostic: static diagnosticId => !(IDEDiagnosticIdToOptionMappingHelper.IsKnownIDEDiagnosticId(diagnosticId) || IsCompilerDiagnostic(diagnosticId)), includeSuppressedDiagnostics: false, cancellationToken: cancellationToken).ConfigureAwait(false)); // ensure more than just compiler diagnostics were returned - var diagnostics = allDiagnostics.WhereAsArray(d => !IsCompilerDiagnostic(d.Id)); if (!diagnostics.Any()) { return document; From e737f03b8b7b76b03290fd982196beebdde3ae83 Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Wed, 23 Feb 2022 11:48:29 -0800 Subject: [PATCH 12/31] report progress per third party fixer --- .../CodeCleanup/AbstractCodeCleanupService.cs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs b/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs index cf275f6f5e031..2fa7557e2e028 100644 --- a/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs +++ b/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs @@ -197,10 +197,18 @@ private async Task ApplyThirdPartyCodeFixesAsync(Document document, IP return document; } - foreach (var diagnosticId in diagnostics.SelectAsArray(static d => d.Id).Distinct()) + var distinctDiagnostics = diagnostics.SelectAsArray(static d => d.Id).Distinct(); + + // ensure progress is reported for each third party code fix + progressTracker.AddItems(distinctDiagnostics.Length); + foreach (var diagnosticId in distinctDiagnostics) { - // Apply codefixes for diagnostics with a severity of warning or higher - document = await _codeFixService.ApplyCodeFixesForSpecificDiagnosticIdAsync(document, diagnosticId, DiagnosticSeverity.Warning, progressTracker, fallbackOptions, cancellationToken).ConfigureAwait(false); + using (progressTracker.ItemCompletedScope(diagnosticId)) + { + // Apply codefixes for diagnostics with a severity of warning or higher + document = await _codeFixService.ApplyCodeFixesForSpecificDiagnosticIdAsync( + document, diagnosticId, DiagnosticSeverity.Warning, progressTracker, fallbackOptions, cancellationToken).ConfigureAwait(false); + } } return document; From f5d6a2d2bb8cf7db2c28f244d24de1e925a37c0c Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Wed, 23 Feb 2022 12:17:23 -0800 Subject: [PATCH 13/31] Do not apply fixes that change more than the current document --- .../CodeCleanup/AbstractCodeCleanupService.cs | 44 +++++++++++++++++-- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs b/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs index 2fa7557e2e028..272163ddd8fc4 100644 --- a/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs +++ b/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs @@ -191,7 +191,7 @@ private async Task ApplyThirdPartyCodeFixesAsync(Document document, IP includeSuppressedDiagnostics: false, cancellationToken: cancellationToken).ConfigureAwait(false)); - // ensure more than just compiler diagnostics were returned + // ensure more than just known diagnostics were returned if (!diagnostics.Any()) { return document; @@ -206,8 +206,17 @@ private async Task ApplyThirdPartyCodeFixesAsync(Document document, IP using (progressTracker.ItemCompletedScope(diagnosticId)) { // Apply codefixes for diagnostics with a severity of warning or higher - document = await _codeFixService.ApplyCodeFixesForSpecificDiagnosticIdAsync( + var updatedDocument = await _codeFixService.ApplyCodeFixesForSpecificDiagnosticIdAsync( document, diagnosticId, DiagnosticSeverity.Warning, progressTracker, fallbackOptions, cancellationToken).ConfigureAwait(false); + + // If changes were made to the solution snap shot outside the current document discard the changes. + // The assumption here is that if we are applying a third party code fix to a document it only affects the document. + // Symbol renames and other complex refactorings we do not want to include in code cleanup. + // We can revisit this if we get feedback to the contrary + if (!ChangesMadeOutsideDocument(document, updatedDocument)) + { + document = updatedDocument; + } } } @@ -217,16 +226,43 @@ static bool IsCompilerDiagnostic(string errorId) { if (!string.IsNullOrEmpty(errorId) && errorId.Length > 2) { - var prefix = errorId.Substring(0, 2); + var prefix = errorId[..2]; if (prefix.Equals("CS", StringComparison.OrdinalIgnoreCase) || prefix.Equals("BC", StringComparison.OrdinalIgnoreCase)) { - var suffix = errorId.Substring(2); + var suffix = errorId[2..]; return int.TryParse(suffix, out _); } } return false; } + + static bool ChangesMadeOutsideDocument(Document currentDocument, Document updatedDocument) + { + var solutionChanges = updatedDocument.Project.Solution.GetChanges(currentDocument.Project.Solution); + if (solutionChanges.GetAddedProjects().Any() || + solutionChanges.GetRemovedProjects().Any() || + solutionChanges.GetAddedAnalyzerReferences().Any() || + solutionChanges.GetRemovedAnalyzerReferences().Any() || + solutionChanges.GetProjectChanges().Any( + projectChanges => projectChanges.GetAddedProjectReferences().Any() || + projectChanges.GetRemovedProjectReferences().Any() || + projectChanges.GetAddedMetadataReferences().Any() || + projectChanges.GetRemovedMetadataReferences().Any() || + projectChanges.GetAddedAnalyzerReferences().Any() || + projectChanges.GetRemovedAnalyzerReferences().Any() || + projectChanges.GetAddedDocuments().Any() || + projectChanges.GetAddedAdditionalDocuments().Any() || + projectChanges.GetAddedAnalyzerConfigDocuments().Any() || + projectChanges.GetChangedDocuments().Any(documentId => documentId != updatedDocument.Id) || + projectChanges.GetChangedAdditionalDocuments().Any(documentId => documentId != updatedDocument.Id) || + projectChanges.GetChangedAnalyzerConfigDocuments().Any(documentId => documentId != updatedDocument.Id))) + { + return true; + } + + return false; + } } public EnabledDiagnosticOptions GetAllDiagnostics() => new EnabledDiagnosticOptions(formatDocument: true, runThirdPartyFixers: true, GetDiagnosticSets(), new OrganizeUsingsSet(isRemoveUnusedImportEnabled: true, isSortImportsEnabled: true)); From 132312726a99662d49447193c02e6e3abde292f6 Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Wed, 23 Feb 2022 18:25:10 -0800 Subject: [PATCH 14/31] add additional C# test cases --- .../Formatting/CodeCleanupTests.TestFixers.cs | 96 +++++++++++++++++++ .../CSharpTest/Formatting/CodeCleanupTests.cs | 91 +++++++++--------- 2 files changed, 139 insertions(+), 48 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.TestFixers.cs b/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.TestFixers.cs index c2c496fedf0f2..5f7bbd9c58a17 100644 --- a/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.TestFixers.cs +++ b/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.TestFixers.cs @@ -5,12 +5,15 @@ #nullable disable using System; +using System.Collections.Generic; using System.Collections.Immutable; using System.Composition; using System.Threading.Tasks; +using System.Windows.Documents; using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Text; namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Formatting { @@ -62,5 +65,98 @@ public TestThirdPartyCodeFixWithOutFixAll() { } } + + [PartNotDiscoverable, Shared, ExportCodeFixProvider(LanguageNames.CSharp)] + private class TestThirdPartyCodeFixModifiesSolution : TestThirdPartyCodeFix + { + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public TestThirdPartyCodeFixModifiesSolution() + { + } + + public override FixAllProvider GetFixAllProvider() => new ModifySolutionFixAll(); + + private class ModifySolutionFixAll : FixAllProvider + { + public override Task GetFixAsync(FixAllContext fixAllContext) + { + var solution = fixAllContext.Solution; + return Task.FromResult(CodeAction.Create( + "Remove default case", + async cancellationToken => + { + var toFix = await fixAllContext.GetDocumentDiagnosticsToFixAsync(); + Project project = null; + foreach (var kvp in toFix) + { + var document = kvp.Key; + project ??= document.Project; + var diagnostics = kvp.Value; + var root = await document.GetSyntaxRootAsync(cancellationToken); + foreach (var diagnostic in diagnostics) + { + var node = (await diagnostic.Location.SourceTree.GetRootAsync(cancellationToken)).FindNode(diagnostic.Location.SourceSpan); + document = document.WithSyntaxRoot(root.RemoveNode(node.Parent, SyntaxRemoveOptions.KeepNoTrivia)); + } + + solution = solution.WithDocumentText(document.Id, await document.GetTextAsync()); + } + + return solution.AddDocument(DocumentId.CreateNewId(project.Id), "new.cs", SourceText.From("")); + }, + nameof(TestThirdPartyCodeFix))); + } + } + } + + [PartNotDiscoverable, Shared, ExportCodeFixProvider(LanguageNames.CSharp)] + private class TestThirdPartyCodeFixDoesNotSupportDocumentScope : TestThirdPartyCodeFix + { + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public TestThirdPartyCodeFixDoesNotSupportDocumentScope() + { + } + + public override FixAllProvider GetFixAllProvider() => new ModifySolutionFixAll(); + + private class ModifySolutionFixAll : FixAllProvider + { + public override IEnumerable GetSupportedFixAllScopes() + { + return new[] { FixAllScope.Project, FixAllScope.Solution, FixAllScope.Custom }; + } + + public override Task GetFixAsync(FixAllContext fixAllContext) + { + var solution = fixAllContext.Solution; + return Task.FromResult(CodeAction.Create( + "Remove default case", + async cancellationToken => + { + var toFix = await fixAllContext.GetDocumentDiagnosticsToFixAsync(); + Project project = null; + foreach (var kvp in toFix) + { + var document = kvp.Key; + project ??= document.Project; + var diagnostics = kvp.Value; + var root = await document.GetSyntaxRootAsync(cancellationToken); + foreach (var diagnostic in diagnostics) + { + var node = (await diagnostic.Location.SourceTree.GetRootAsync(cancellationToken)).FindNode(diagnostic.Location.SourceSpan); + document = document.WithSyntaxRoot(root.RemoveNode(node.Parent, SyntaxRemoveOptions.KeepNoTrivia)); + } + + solution = solution.WithDocumentText(document.Id, await document.GetTextAsync()); + } + + return solution.AddDocument(DocumentId.CreateNewId(project.Id), "new.cs", SourceText.From("")); + }, + nameof(TestThirdPartyCodeFix))); + } + } + } } } diff --git a/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs b/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs index 345839ca94e21..c2336eeca0572 100644 --- a/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs +++ b/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs @@ -4,6 +4,7 @@ #nullable disable +using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; @@ -29,6 +30,7 @@ using Microsoft.CodeAnalysis.Simplification; using Microsoft.CodeAnalysis.SolutionCrawler; using Microsoft.CodeAnalysis.Test.Utilities; +using Microsoft.CodeAnalysis.Text; using Microsoft.CodeAnalysis.UnitTests.Diagnostics; using Roslyn.Test.Utilities; using Xunit; @@ -575,11 +577,7 @@ public void VerifyAllCodeStyleFixersAreSupportedByCodeCleanup(string language, i Assert.Equal(expectedNumberOfUnsupportedDiagnosticIds, unsupportedDiagnosticIds.Length); } - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeCleanup)] - public async Task RunThirdPartyFixer() - { - const string code = @" + private const string _code = @" class C { public void M1(int x, int y) @@ -628,7 +626,7 @@ public void M1(int x, int y) } "; - const string expected = @" + private const string _fixed = @" class C { public void M1(int x, int y) @@ -669,66 +667,54 @@ public void M1(int x, int y) } } "; - await TestThirdPartyCodeFixer(code, expected); - } [Fact] [Trait(Traits.Feature, Traits.Features.CodeCleanup)] - public async Task DoNotRunThirdPartyFixerWithNoFixAll() - { - const string code = @" -class C -{ - public void M1(int x, int y) - { - switch (x) + public async Task RunThirdPartyFixer() { - case 1: - case 10: - break; - default: - break; + await TestThirdPartyCodeFixer(_code, _fixed); } - switch (y) + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeCleanup)] + public async Task DoNotRunThirdPartyFixerWithNoFixAll() { - case 1: - break; - case 1000: - default: - break; + await TestThirdPartyCodeFixer(_code, _code); } - switch (x) + [Theory] + [InlineData(DiagnosticSeverity.Warning)] + [InlineData(DiagnosticSeverity.Error)] + [Trait(Traits.Feature, Traits.Features.CodeCleanup)] + public async Task RunThirdPartyFixerWithSeverityOfWarningOrHigher(DiagnosticSeverity severity) { - case 1: - break; - case 1000: - break; + await TestThirdPartyCodeFixer(_code, _fixed, severity); } - switch (y) + [Theory] + [InlineData(DiagnosticSeverity.Hidden)] + [InlineData(DiagnosticSeverity.Info)] + [Trait(Traits.Feature, Traits.Features.CodeCleanup)] + public async Task DoNotRunThirdPartyFixerWithSeverityLessThanWarning(DiagnosticSeverity severity) { - default: - break; + await TestThirdPartyCodeFixer(_code, _code, severity); } - switch (y) { } - - switch (x) + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeCleanup)] + public async Task DoNotRunThirdPartyFixerIfItDoesNotSupportDocumentScope() { - case : - case 1000: - break; + await TestThirdPartyCodeFixer(_code, _code); } - } -} -"; - await TestThirdPartyCodeFixer(code, code); + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeCleanup)] + public async Task DoNotApplyFixerIfChangesAreMadeOutsideDocument() + { + await TestThirdPartyCodeFixer(_code, _code); } - private static async Task TestThirdPartyCodeFixer(string code, string expected) + private static async Task TestThirdPartyCodeFixer(string code, string expected, DiagnosticSeverity severity = DiagnosticSeverity.Warning) where TAnalyzer : DiagnosticAnalyzer, new() where TCodefix : CodeFixProvider, new() { @@ -738,13 +724,22 @@ private static async Task TestThirdPartyCodeFixer(string co var options = CodeActionOptions.DefaultProvider; var project = workspace.CurrentSolution.Projects.Single(); + var analyzer = (DiagnosticAnalyzer)new TAnalyzer(); + var diagnosticIds = analyzer.SupportedDiagnostics.SelectAsArray(d => d.Id); + + var editorconfigText = "is_global = true"; + foreach (var diagnosticId in diagnosticIds) + { + editorconfigText += $"\ndotnet_diagnostic.{diagnosticId}.severity = {severity.ToEditorConfigString()}"; + } var map = new Dictionary>{ - { LanguageNames.CSharp, ImmutableArray.Create((DiagnosticAnalyzer)new TAnalyzer()) } + { LanguageNames.CSharp, ImmutableArray.Create(analyzer) } }; project = project.AddAnalyzerReference(new TestAnalyzerReferenceByLanguage(map)); - + project = project.Solution.WithProjectFilePath(project.Id, @$"z:\\{project.FilePath}").GetProject(project.Id); + project = project.AddAnalyzerConfigDocument(".editorconfig", SourceText.From(editorconfigText), filePath: @"z:\\.editorconfig").Project; workspace.TryApplyChanges(project.Solution); // register this workspace to solution crawler so that analyzer service associate itself with given workspace From bbb242a142654ec9f4eafc66d88015af87af454e Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Wed, 23 Feb 2022 18:57:10 -0800 Subject: [PATCH 15/31] adding additional VB tests --- .../Formatting/CodeCleanUpTests.vb | 217 +++++++++++------- 1 file changed, 132 insertions(+), 85 deletions(-) diff --git a/src/EditorFeatures/VisualBasicTest/Formatting/CodeCleanUpTests.vb b/src/EditorFeatures/VisualBasicTest/Formatting/CodeCleanUpTests.vb index 0c4cf3c55e6b3..8334dd03b1f70 100644 --- a/src/EditorFeatures/VisualBasicTest/Formatting/CodeCleanUpTests.vb +++ b/src/EditorFeatures/VisualBasicTest/Formatting/CodeCleanUpTests.vb @@ -22,6 +22,7 @@ Imports Microsoft.CodeAnalysis.Options Imports Microsoft.CodeAnalysis.Shared.Utilities Imports Microsoft.CodeAnalysis.SolutionCrawler Imports Microsoft.CodeAnalysis.VisualBasic.CodeGeneration +Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.UnitTests.Diagnostics Imports Microsoft.CodeAnalysis.VisualBasic.Diagnostics.Analyzers Imports Microsoft.CodeAnalysis.VisualBasic.Formatting @@ -328,10 +329,7 @@ End Class Return AssertCodeCleanupResultAsync(expected, code) End Function - - - Public Shared Async Function RunThirdPartyFixer() As Task - Dim code As String = " + Private Const _code As String = " Class C Public Sub M1(x As Integer) Select Case x @@ -411,7 +409,8 @@ Class C End Sub End Class " - Dim expected As String = " + + Private Const _expected As String = " Class C Public Sub M1(x As Integer) Select Case x @@ -481,96 +480,48 @@ Class C End Sub End Class " - Await TestThirdPartyCodeFixer(Of TestThirdPartyCodeFixWithFixAll, CaseTestAnalyzer)(expected, code) - End Function - Public Shared Async Function DoNotRunThirdPartyFixerWithNoFixAll() As Task - Dim code As String = " -Class C - Public Sub M1(x As Integer) - Select Case x - Case 1, 2 - Exit Select - Case = 10 - Exit Select - Case Else - Exit Select - End Select - - Select Case x - Case 1 - Exit Select - Case = 1000 - Exit Select - Case Else - Exit Select - End Select - - Select Case x - Case 10 To 500 - Exit Select - Case = 1000 - Exit Select - Case Else - Exit Select - End Select - - Select Case x - Case 1, 980 To 985 - Exit Select - Case Else - Exit Select - End Select - - Select Case x - Case 1 to 3, 980 To 985 - Exit Select - End Select - - Select Case x - Case 1 - Exit Select - Case > 100000 - Exit Select - End Select + Public Shared Async Function RunThirdPartyFixer() As Task + Await TestThirdPartyCodeFixer(Of TestThirdPartyCodeFixWithFixAll, CaseTestAnalyzer)(_expected, _code) + End Function - Select Case x - Case Else - Exit Select - End Select + + + + + Public Shared Async Function RunThirdPartyFixerWithSeverityOfWarningOrHigher(severity As DiagnosticSeverity) As Task + Await TestThirdPartyCodeFixer(Of TestThirdPartyCodeFixWithFixAll, CaseTestAnalyzer)(_expected, _code, severity) + End Function - Select Case x - End Select + + + + + Public Shared Async Function DoNotRunThirdPartyFixerWithSeverityLessThanWarning(severity As DiagnosticSeverity) As Task + Await TestThirdPartyCodeFixer(Of TestThirdPartyCodeFixWithFixAll, CaseTestAnalyzer)(_code, _code, severity) + End Function - Select Case x - Case 1 - Exit Select - Case - Exit Select - End Select + + + Public Shared Async Function DoNotRunThirdPartyFixerIfItDoesNotSupportDocumentScope() As Task + Await TestThirdPartyCodeFixer(Of TestThirdPartyCodeFixDoesNotSupportDocumentScope, CaseTestAnalyzer)(_code, _code) + End Function - Select Case x - Case 1 - Exit Select - Case = - Exit Select - End Select + + + Public Shared Async Function DoNotApplyFixerIfChangesAreMadeOutsideDocument() As Task + Await TestThirdPartyCodeFixer(Of TestThirdPartyCodeFixModifiesSolution, CaseTestAnalyzer)(_code, _code) + End Function - Select Case x - Case 1 - Exit Select - Case 2 to - Exit Select - End Select - End Sub -End Class -" - Await TestThirdPartyCodeFixer(Of TestThirdPartyCodeFixWithOutFixAll, CaseTestAnalyzer)(code, code) + + + Public Shared Async Function DoNotRunThirdPartyFixerWithNoFixAll() As Task + Await TestThirdPartyCodeFixer(Of TestThirdPartyCodeFixWithOutFixAll, CaseTestAnalyzer)(_code, _code) End Function - Private Shared Async Function TestThirdPartyCodeFixer(Of TCodefix As {CodeFixProvider, New}, TAnalyzer As {DiagnosticAnalyzer, New})(expected As String, code As String) As Task + Private Shared Async Function TestThirdPartyCodeFixer(Of TCodefix As {CodeFixProvider, New}, TAnalyzer As {DiagnosticAnalyzer, New})(expected As String, code As String, Optional severity As DiagnosticSeverity = DiagnosticSeverity.Warning) As Task Using workspace = TestWorkspace.CreateVisualBasic(code, composition:=EditorTestCompositions.EditorFeaturesWpf.AddParts(GetType(TCodefix))) Dim options = CodeActionOptions.DefaultProvider Dim project = workspace.CurrentSolution.Projects.Single() @@ -578,7 +529,17 @@ End Class { {LanguageNames.VisualBasic, ImmutableArray.Create(Of DiagnosticAnalyzer)(New TAnalyzer())} } + Dim analyzer As DiagnosticAnalyzer = New TAnalyzer() + Dim diagnosticIds = analyzer.SupportedDiagnostics.SelectAsArray(Function(d) d.Id) + + Dim editorconfigText = "is_global = true" + For Each diagnosticId In diagnosticIds + editorconfigText += $"{Environment.NewLine}dotnet_diagnostic.{diagnosticId}.severity = {severity.ToEditorConfigString()}" + Next + project = project.AddAnalyzerReference(New TestAnalyzerReferenceByLanguage(map)) + project = project.Solution.WithProjectFilePath(project.Id, $"z:\\{project.FilePath}").GetProject(project.Id) + project = project.AddAnalyzerConfigDocument(".editorconfig", SourceText.From(editorconfigText), filePath:="z:\\.editorconfig").Project workspace.TryApplyChanges(project.Solution) ' register this workspace to solution crawler so that analyzer service associate itself with given workspace @@ -679,6 +640,92 @@ End Class End Sub End Class + + Private Class TestThirdPartyCodeFixModifiesSolution : Inherits TestThirdPartyCodeFix + + + + Public Sub New() + End Sub + + Public Overrides Function GetFixAllProvider() As FixAllProvider + Return New ModifySolutionFixAll + End Function + + Private Class ModifySolutionFixAll : Inherits FixAllProvider + + Public Overrides Function GetFixAsync(fixAllContext As FixAllContext) As Task(Of CodeAction) + Dim solution = fixAllContext.Solution + Return Task.FromResult(CodeAction.Create( + "Remove default case", + Async Function(cancellationToken) + Dim toFix = Await fixAllContext.GetDocumentDiagnosticsToFixAsync() + Dim project As Project = Nothing + For Each kvp In toFix + Dim document = kvp.Key + project = document.Project + Dim diagnostics = kvp.Value + Dim root = Await document.GetSyntaxRootAsync(cancellationToken) + For Each diagnostic In diagnostics + Dim node = (Await diagnostic.Location.SourceTree.GetRootAsync(cancellationToken)).FindNode(diagnostic.Location.SourceSpan) + document = document.WithSyntaxRoot(root.RemoveNode(node.Parent, SyntaxRemoveOptions.KeepNoTrivia)) + Next + + solution = solution.WithDocumentText(document.Id, Await document.GetTextAsync()) + Next + + Return solution.AddDocument(DocumentId.CreateNewId(project.Id), "new.vb", SourceText.From("")) + End Function, + NameOf(TestThirdPartyCodeFix))) + End Function + End Class + End Class + + + Private Class TestThirdPartyCodeFixDoesNotSupportDocumentScope : Inherits TestThirdPartyCodeFix + + + + Public Sub New() + End Sub + + Public Overrides Function GetFixAllProvider() As FixAllProvider + Return New ModifySolutionFixAll + End Function + + Private Class ModifySolutionFixAll : Inherits FixAllProvider + + Public Overrides Function GetSupportedFixAllScopes() As IEnumerable(Of FixAllScope) + Return {FixAllScope.Project, FixAllScope.Solution, FixAllScope.Custom} + End Function + + Public Overrides Function GetFixAsync(fixAllContext As FixAllContext) As Task(Of CodeAction) + Dim solution = fixAllContext.Solution + Return Task.FromResult(CodeAction.Create( + "Remove default case", + Async Function(cancellationToken) + Dim toFix = Await fixAllContext.GetDocumentDiagnosticsToFixAsync() + Dim project As Project = Nothing + For Each kvp In toFix + Dim document = kvp.Key + project = document.Project + Dim diagnostics = kvp.Value + Dim root = Await document.GetSyntaxRootAsync(cancellationToken) + For Each diagnostic In diagnostics + Dim node = (Await diagnostic.Location.SourceTree.GetRootAsync(cancellationToken)).FindNode(diagnostic.Location.SourceSpan) + document = document.WithSyntaxRoot(root.RemoveNode(node.Parent, SyntaxRemoveOptions.KeepNoTrivia)) + Next + + solution = solution.WithDocumentText(document.Id, Await document.GetTextAsync()) + Next + + Return solution.AddDocument(DocumentId.CreateNewId(project.Id), "new.vb", SourceText.From("")) + End Function, + NameOf(TestThirdPartyCodeFix))) + End Function + End Class + End Class + Private Class TestThirdPartyCodeFix : Inherits CodeFixProvider Public Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) From 0678c6799ca797335a61d2bfae759a9dab9308c0 Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Tue, 1 Mar 2022 11:51:12 -0800 Subject: [PATCH 16/31] use helper methods --- .../CSharpTest/Formatting/CodeCleanupTests.cs | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs b/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs index c2336eeca0572..b0a219f6cf895 100644 --- a/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs +++ b/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs @@ -672,14 +672,14 @@ public void M1(int x, int y) [Trait(Traits.Feature, Traits.Features.CodeCleanup)] public async Task RunThirdPartyFixer() { - await TestThirdPartyCodeFixer(_code, _fixed); + await TestThirdPartyCodeFixerApplied(_code, _fixed); } [Fact] [Trait(Traits.Feature, Traits.Features.CodeCleanup)] public async Task DoNotRunThirdPartyFixerWithNoFixAll() { - await TestThirdPartyCodeFixer(_code, _code); + await TestThirdPartyCodeFixerNoChanges(_code); } [Theory] @@ -688,7 +688,7 @@ public async Task DoNotRunThirdPartyFixerWithNoFixAll() [Trait(Traits.Feature, Traits.Features.CodeCleanup)] public async Task RunThirdPartyFixerWithSeverityOfWarningOrHigher(DiagnosticSeverity severity) { - await TestThirdPartyCodeFixer(_code, _fixed, severity); + await TestThirdPartyCodeFixerApplied(_code, _fixed, severity); } [Theory] @@ -697,24 +697,38 @@ public async Task RunThirdPartyFixerWithSeverityOfWarningOrHigher(DiagnosticSeve [Trait(Traits.Feature, Traits.Features.CodeCleanup)] public async Task DoNotRunThirdPartyFixerWithSeverityLessThanWarning(DiagnosticSeverity severity) { - await TestThirdPartyCodeFixer(_code, _code, severity); + await TestThirdPartyCodeFixerNoChanges(_code, severity); } [Fact] [Trait(Traits.Feature, Traits.Features.CodeCleanup)] public async Task DoNotRunThirdPartyFixerIfItDoesNotSupportDocumentScope() { - await TestThirdPartyCodeFixer(_code, _code); + await TestThirdPartyCodeFixerNoChanges(_code); } [Fact] [Trait(Traits.Feature, Traits.Features.CodeCleanup)] public async Task DoNotApplyFixerIfChangesAreMadeOutsideDocument() { - await TestThirdPartyCodeFixer(_code, _code); + await TestThirdPartyCodeFixerNoChanges(_code); } - private static async Task TestThirdPartyCodeFixer(string code, string expected, DiagnosticSeverity severity = DiagnosticSeverity.Warning) + private static Task TestThirdPartyCodeFixerNoChanges(string code, DiagnosticSeverity severity = DiagnosticSeverity.Warning) + where TAnalyzer : DiagnosticAnalyzer, new() + where TCodefix : CodeFixProvider, new() + { + return TestThirdPartyCodeFixer(code, code, severity); + } + + private static Task TestThirdPartyCodeFixerApplied(string code, string expected, DiagnosticSeverity severity = DiagnosticSeverity.Warning) + where TAnalyzer : DiagnosticAnalyzer, new() + where TCodefix : CodeFixProvider, new() + { + return TestThirdPartyCodeFixer(code, expected, severity); + } + + private static async Task TestThirdPartyCodeFixer(string code = null, string expected = null, DiagnosticSeverity severity = DiagnosticSeverity.Warning) where TAnalyzer : DiagnosticAnalyzer, new() where TCodefix : CodeFixProvider, new() { From 34758110c4f5cffdad0ebc5fe5dbb991675eda3d Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Tue, 1 Mar 2022 15:55:17 -0800 Subject: [PATCH 17/31] enable nullable tracking for test fixes --- .../Formatting/CodeCleanupTests.TestFixers.cs | 47 +++++++++++++------ 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.TestFixers.cs b/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.TestFixers.cs index 5f7bbd9c58a17..5665f1ed2ffcb 100644 --- a/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.TestFixers.cs +++ b/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.TestFixers.cs @@ -2,14 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Composition; using System.Threading.Tasks; -using System.Windows.Documents; using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Host.Mef; @@ -33,8 +30,14 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) async cancellationToken => { var root = await context.Document.GetSyntaxRootAsync(cancellationToken); - var node = (await diagnostic.Location.SourceTree.GetRootAsync(cancellationToken)).FindNode(diagnostic.Location.SourceSpan); - return context.Document.WithSyntaxRoot(root.RemoveNode(node.Parent, SyntaxRemoveOptions.KeepNoTrivia)); + Assumes.NotNull(root); + var sourceTree = diagnostic.Location.SourceTree; + Assumes.NotNull(sourceTree); + var node = (await sourceTree.GetRootAsync(cancellationToken)).FindNode(diagnostic.Location.SourceSpan); + Assumes.NotNull(node?.Parent); + var newRoot = root.RemoveNode(node.Parent, SyntaxRemoveOptions.KeepNoTrivia); + Assumes.NotNull(newRoot); + return context.Document.WithSyntaxRoot(newRoot); }, nameof(TestThirdPartyCodeFix)), diagnostic); @@ -79,30 +82,37 @@ public TestThirdPartyCodeFixModifiesSolution() private class ModifySolutionFixAll : FixAllProvider { - public override Task GetFixAsync(FixAllContext fixAllContext) + public override Task GetFixAsync(FixAllContext fixAllContext) { var solution = fixAllContext.Solution; - return Task.FromResult(CodeAction.Create( + return Task.FromResult(CodeAction.Create( "Remove default case", async cancellationToken => { var toFix = await fixAllContext.GetDocumentDiagnosticsToFixAsync(); - Project project = null; + Project? project = null; foreach (var kvp in toFix) { var document = kvp.Key; project ??= document.Project; var diagnostics = kvp.Value; var root = await document.GetSyntaxRootAsync(cancellationToken); + Assumes.NotNull(root); foreach (var diagnostic in diagnostics) { - var node = (await diagnostic.Location.SourceTree.GetRootAsync(cancellationToken)).FindNode(diagnostic.Location.SourceSpan); - document = document.WithSyntaxRoot(root.RemoveNode(node.Parent, SyntaxRemoveOptions.KeepNoTrivia)); + var sourceTree = diagnostic.Location.SourceTree; + Assumes.NotNull(sourceTree); + var node = (await sourceTree.GetRootAsync(cancellationToken)).FindNode(diagnostic.Location.SourceSpan); + Assumes.NotNull(node?.Parent); + var newRoot = root.RemoveNode(node.Parent, SyntaxRemoveOptions.KeepNoTrivia); + Assumes.NotNull(newRoot); + document = document.WithSyntaxRoot(newRoot); } solution = solution.WithDocumentText(document.Id, await document.GetTextAsync()); } + Assumes.NotNull(project); return solution.AddDocument(DocumentId.CreateNewId(project.Id), "new.cs", SourceText.From("")); }, nameof(TestThirdPartyCodeFix))); @@ -128,30 +138,37 @@ public override IEnumerable GetSupportedFixAllScopes() return new[] { FixAllScope.Project, FixAllScope.Solution, FixAllScope.Custom }; } - public override Task GetFixAsync(FixAllContext fixAllContext) + public override Task GetFixAsync(FixAllContext fixAllContext) { var solution = fixAllContext.Solution; - return Task.FromResult(CodeAction.Create( + return Task.FromResult(CodeAction.Create( "Remove default case", async cancellationToken => { var toFix = await fixAllContext.GetDocumentDiagnosticsToFixAsync(); - Project project = null; + Project? project = null; foreach (var kvp in toFix) { var document = kvp.Key; project ??= document.Project; var diagnostics = kvp.Value; var root = await document.GetSyntaxRootAsync(cancellationToken); + Assumes.NotNull(root); foreach (var diagnostic in diagnostics) { - var node = (await diagnostic.Location.SourceTree.GetRootAsync(cancellationToken)).FindNode(diagnostic.Location.SourceSpan); - document = document.WithSyntaxRoot(root.RemoveNode(node.Parent, SyntaxRemoveOptions.KeepNoTrivia)); + var sourceTree = diagnostic.Location.SourceTree; + Assumes.NotNull(sourceTree); + var node = (await sourceTree.GetRootAsync(cancellationToken)).FindNode(diagnostic.Location.SourceSpan); + Assumes.NotNull(node?.Parent); + var newRoot = root.RemoveNode(node.Parent, SyntaxRemoveOptions.KeepNoTrivia); + Assumes.NotNull(newRoot); + document = document.WithSyntaxRoot(newRoot); } solution = solution.WithDocumentText(document.Id, await document.GetTextAsync()); } + Assumes.NotNull(project); return solution.AddDocument(DocumentId.CreateNewId(project.Id), "new.cs", SourceText.From("")); }, nameof(TestThirdPartyCodeFix))); From 0c2c910ad1b32da50b248c858b5772f1075ad9f4 Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Tue, 1 Mar 2022 17:05:16 -0800 Subject: [PATCH 18/31] Update src/Features/Core/Portable/CodeCleanup/AbstractCodeCleanupService.cs Co-authored-by: CyrusNajmabadi --- .../Features/CodeCleanup/AbstractCodeCleanupService.cs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs b/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs index 272163ddd8fc4..f71ac6e6d1283 100644 --- a/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs +++ b/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs @@ -240,7 +240,8 @@ static bool IsCompilerDiagnostic(string errorId) static bool ChangesMadeOutsideDocument(Document currentDocument, Document updatedDocument) { var solutionChanges = updatedDocument.Project.Solution.GetChanges(currentDocument.Project.Solution); - if (solutionChanges.GetAddedProjects().Any() || + return + solutionChanges.GetAddedProjects().Any() || solutionChanges.GetRemovedProjects().Any() || solutionChanges.GetAddedAnalyzerReferences().Any() || solutionChanges.GetRemovedAnalyzerReferences().Any() || @@ -256,12 +257,7 @@ static bool ChangesMadeOutsideDocument(Document currentDocument, Document update projectChanges.GetAddedAnalyzerConfigDocuments().Any() || projectChanges.GetChangedDocuments().Any(documentId => documentId != updatedDocument.Id) || projectChanges.GetChangedAdditionalDocuments().Any(documentId => documentId != updatedDocument.Id) || - projectChanges.GetChangedAnalyzerConfigDocuments().Any(documentId => documentId != updatedDocument.Id))) - { - return true; - } - - return false; + projectChanges.GetChangedAnalyzerConfigDocuments().Any(documentId => documentId != updatedDocument.Id)); } } public EnabledDiagnosticOptions GetAllDiagnostics() From ad987bf963f9bcdecd723e5eda4d0ec584c9b741 Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Fri, 4 Mar 2022 14:42:52 -0800 Subject: [PATCH 19/31] rename method for clarity --- src/Features/Core/Portable/CodeFixes/DiagnosticExtensions.cs | 2 +- .../Protocol/Features/CodeFixes/CodeFixService.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Features/Core/Portable/CodeFixes/DiagnosticExtensions.cs b/src/Features/Core/Portable/CodeFixes/DiagnosticExtensions.cs index ae65ba6247759..f01788ccef5d9 100644 --- a/src/Features/Core/Portable/CodeFixes/DiagnosticExtensions.cs +++ b/src/Features/Core/Portable/CodeFixes/DiagnosticExtensions.cs @@ -9,7 +9,7 @@ namespace Microsoft.CodeAnalysis.CodeFixes { internal static class DiagnosticExtensions { - public static bool GreaterThanOrEqualTo(this DiagnosticSeverity left, DiagnosticSeverity right) + public static bool IsMoreSevereThanOrEqualTo(this DiagnosticSeverity left, DiagnosticSeverity right) { var leftInt = (int)left; var rightInt = (int)right; diff --git a/src/Features/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs b/src/Features/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs index 754a4d8dd41f5..4299b47b1688e 100644 --- a/src/Features/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs +++ b/src/Features/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs @@ -241,7 +241,7 @@ private static SortedDictionary> ConvertToMap( var diagnostics = await _diagnosticService.GetDiagnosticsForSpanAsync( document, range, diagnosticId, includeSuppressedDiagnostics: false, cancellationToken: cancellationToken).ConfigureAwait(false); - diagnostics = diagnostics.WhereAsArray(d => d.Severity.GreaterThanOrEqualTo(minimumSeverity)); + diagnostics = diagnostics.WhereAsArray(d => d.Severity.IsMoreSevereThanOrEqualTo(minimumSeverity)); if (!diagnostics.Any()) return null; From be77781844f621caadd3614e7a0c42c89f575252 Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Fri, 4 Mar 2022 15:26:17 -0800 Subject: [PATCH 20/31] update progress to never "rewind" and report the correct number of fixers up front --- .../Core/Portable/FeaturesResources.resx | 3 + .../Portable/xlf/FeaturesResources.cs.xlf | 5 ++ .../Portable/xlf/FeaturesResources.de.xlf | 5 ++ .../Portable/xlf/FeaturesResources.es.xlf | 5 ++ .../Portable/xlf/FeaturesResources.fr.xlf | 5 ++ .../Portable/xlf/FeaturesResources.it.xlf | 5 ++ .../Portable/xlf/FeaturesResources.ja.xlf | 5 ++ .../Portable/xlf/FeaturesResources.ko.xlf | 5 ++ .../Portable/xlf/FeaturesResources.pl.xlf | 5 ++ .../Portable/xlf/FeaturesResources.pt-BR.xlf | 5 ++ .../Portable/xlf/FeaturesResources.ru.xlf | 5 ++ .../Portable/xlf/FeaturesResources.tr.xlf | 5 ++ .../xlf/FeaturesResources.zh-Hans.xlf | 5 ++ .../xlf/FeaturesResources.zh-Hant.xlf | 5 ++ .../CodeCleanup/AbstractCodeCleanupService.cs | 64 +++++++++++-------- 15 files changed, 104 insertions(+), 28 deletions(-) diff --git a/src/Features/Core/Portable/FeaturesResources.resx b/src/Features/Core/Portable/FeaturesResources.resx index 06a7ef02494f2..543c6dfc7919f 100644 --- a/src/Features/Core/Portable/FeaturesResources.resx +++ b/src/Features/Core/Portable/FeaturesResources.resx @@ -3141,4 +3141,7 @@ Zero-width positive lookbehind assertions are typically used at the beginning of Replace conditional expression with statements + + Fixing '{0}' + \ No newline at end of file diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf index 6272f5f7e13d8..8110da56142bc 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf @@ -730,6 +730,11 @@ Ujistěte se, že specifikátor tt použijete pro jazyky, pro které je nezbytn Opravit překlep {0} + + Fixing '{0}' + Fixing '{0}' + + Formatting document Formátuje se dokument. diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf index 30bec1315ebb2..6654f16f6746b 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf @@ -730,6 +730,11 @@ Stellen Sie sicher, dass Sie den Bezeichner "tt" für Sprachen verwenden, für d Tippfehler "{0}" korrigieren + + Fixing '{0}' + Fixing '{0}' + + Formatting document Dokument wird formatiert diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf index 14920e26322f8..ef2958237233d 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf @@ -730,6 +730,11 @@ Asegúrese de usar el especificador "tt" para los idiomas para los que es necesa Corregir error de escritura "{0}" + + Fixing '{0}' + Fixing '{0}' + + Formatting document Aplicando formato al documento diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf index 6f6329b8094ae..517e3342d2a4b 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf @@ -730,6 +730,11 @@ Veillez à utiliser le spécificateur "tt" pour les langues où il est nécessai Corriger la faute de frappe '{0}' + + Fixing '{0}' + Fixing '{0}' + + Formatting document Mise en forme du document diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf index e47eeafceb0cc..007f5db6a4451 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf @@ -730,6 +730,11 @@ Assicurarsi di usare l'identificatore "tt" per le lingue per le quali è necessa Correggi l'errore di ortografia '{0}' + + Fixing '{0}' + Fixing '{0}' + + Formatting document Formattazione del documento diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf index f622afb23f54f..c5dfa0f4f9c7d 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf @@ -730,6 +730,11 @@ Make sure to use the "tt" specifier for languages for which it's necessary to ma '{0}' の入力ミスを修正します + + Fixing '{0}' + Fixing '{0}' + + Formatting document ドキュメントの書式設定 diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf index aa54f807562da..2f883645cfb87 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf @@ -730,6 +730,11 @@ Make sure to use the "tt" specifier for languages for which it's necessary to ma 오타 '{0}' 수정 + + Fixing '{0}' + Fixing '{0}' + + Formatting document 문서 서식을 지정하는 중 diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf index 8d8067dec9ca5..eb58a8b2c484f 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf @@ -730,6 +730,11 @@ Pamiętaj, aby nie używać specyfikatora „tt” dla wszystkich języków, w k Popraw błąd pisowni „{0}” + + Fixing '{0}' + Fixing '{0}' + + Formatting document Trwa formatowanie dokumentu... diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf index b9be640f8efdc..091feb8e59cdf 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf @@ -730,6 +730,11 @@ Verifique se o especificador "tt" foi usado para idiomas para os quais é necess Corrigir erro de digitação '{0}' + + Fixing '{0}' + Fixing '{0}' + + Formatting document Formatando documento diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf index 645be4994179a..4c7d6310d4b3c 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf @@ -730,6 +730,11 @@ Make sure to use the "tt" specifier for languages for which it's necessary to ma Исправьте опечатку "{0}" + + Fixing '{0}' + Fixing '{0}' + + Formatting document Форматирование документа diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf index d6e886a3d2a96..5f9b38e754d25 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf @@ -730,6 +730,11 @@ AM ve PM arasındaki farkın korunmasının gerekli olduğu diller için "tt" be '{0}' yazım hatasını düzeltin + + Fixing '{0}' + Fixing '{0}' + + Formatting document Belge biçimlendiriliyor diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf index 5eab4b5030084..b0fc72c39cc07 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf @@ -730,6 +730,11 @@ Make sure to use the "tt" specifier for languages for which it's necessary to ma 修正笔误“{0}” + + Fixing '{0}' + Fixing '{0}' + + Formatting document 设置文档格式 diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf index 97623154c7b3b..3d76887cc9cd5 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf @@ -730,6 +730,11 @@ Make sure to use the "tt" specifier for languages for which it's necessary to ma 修正錯字 '{0}' + + Fixing '{0}' + Fixing '{0}' + + Formatting document 正在將文件格式化 diff --git a/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs b/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs index f71ac6e6d1283..1a4fe274679f5 100644 --- a/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs +++ b/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs @@ -44,9 +44,11 @@ public async Task CleanupAsync( CancellationToken cancellationToken) { // add one item for the code fixers we get from nuget, we'll do last + var thirdPartyDiagnosticIdsAndTitles = ImmutableArray<(string diagnosticId, string? title)>.Empty; if (enabledDiagnostics.RunThirdPartyFixers) { - progressTracker.AddItems(1); + thirdPartyDiagnosticIdsAndTitles = await GetThirdPartyDiagnosticIdsAndTitlesAsync(document, cancellationToken).ConfigureAwait(false); + progressTracker.AddItems(thirdPartyDiagnosticIdsAndTitles.Length); } // add one item for the 'format' action @@ -90,7 +92,7 @@ public async Task CleanupAsync( if (enabledDiagnostics.RunThirdPartyFixers) { document = await ApplyThirdPartyCodeFixesAsync( - document, progressTracker, fallbackOptions, cancellationToken).ConfigureAwait(false); + document, thirdPartyDiagnosticIdsAndTitles, progressTracker, fallbackOptions, cancellationToken).ConfigureAwait(false); progressTracker.ItemCompleted(); } @@ -180,7 +182,7 @@ private async Task ApplyCodeFixesForSpecificDiagnosticIdAsync(Document return solution.GetDocument(document.Id) ?? throw new NotSupportedException(FeaturesResources.Removal_of_document_not_supported); } - private async Task ApplyThirdPartyCodeFixesAsync(Document document, IProgressTracker progressTracker, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) + private async Task> GetThirdPartyDiagnosticIdsAndTitlesAsync(Document document, CancellationToken cancellationToken) { var tree = await document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); var range = new TextSpan(0, tree.Length); @@ -194,33 +196,10 @@ private async Task ApplyThirdPartyCodeFixesAsync(Document document, IP // ensure more than just known diagnostics were returned if (!diagnostics.Any()) { - return document; + return ImmutableArray<(string diagnosticId, string? title)>.Empty; } - var distinctDiagnostics = diagnostics.SelectAsArray(static d => d.Id).Distinct(); - - // ensure progress is reported for each third party code fix - progressTracker.AddItems(distinctDiagnostics.Length); - foreach (var diagnosticId in distinctDiagnostics) - { - using (progressTracker.ItemCompletedScope(diagnosticId)) - { - // Apply codefixes for diagnostics with a severity of warning or higher - var updatedDocument = await _codeFixService.ApplyCodeFixesForSpecificDiagnosticIdAsync( - document, diagnosticId, DiagnosticSeverity.Warning, progressTracker, fallbackOptions, cancellationToken).ConfigureAwait(false); - - // If changes were made to the solution snap shot outside the current document discard the changes. - // The assumption here is that if we are applying a third party code fix to a document it only affects the document. - // Symbol renames and other complex refactorings we do not want to include in code cleanup. - // We can revisit this if we get feedback to the contrary - if (!ChangesMadeOutsideDocument(document, updatedDocument)) - { - document = updatedDocument; - } - } - } - - return document; + return diagnostics.SelectAsArray(static d => (d.Id, d.Title)).Distinct(); static bool IsCompilerDiagnostic(string errorId) { @@ -236,6 +215,35 @@ static bool IsCompilerDiagnostic(string errorId) return false; } + } + + private async Task ApplyThirdPartyCodeFixesAsync( + Document document, + ImmutableArray<(string diagnosticId, string? title)> diagnosticIds, + IProgressTracker progressTracker, + CodeActionOptionsProvider fallbackOptions, + CancellationToken cancellationToken) + { + foreach (var (diagnosticId, title) in diagnosticIds) + { + progressTracker.Description = string.Format(FeaturesResources.Fixing_0, title ?? diagnosticId); + // Apply codefixes for diagnostics with a severity of warning or higher + var updatedDocument = await _codeFixService.ApplyCodeFixesForSpecificDiagnosticIdAsync( + document, diagnosticId, DiagnosticSeverity.Warning, progressTracker, fallbackOptions, cancellationToken).ConfigureAwait(false); + + // If changes were made to the solution snap shot outside the current document discard the changes. + // The assumption here is that if we are applying a third party code fix to a document it only affects the document. + // Symbol renames and other complex refactorings we do not want to include in code cleanup. + // We can revisit this if we get feedback to the contrary + if (!ChangesMadeOutsideDocument(document, updatedDocument)) + { + document = updatedDocument; + } + + progressTracker.ItemCompleted(); + } + + return document; static bool ChangesMadeOutsideDocument(Document currentDocument, Document updatedDocument) { From c934e6c3e08251c53fcb47c7120e6e54f85ff77b Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Fri, 4 Mar 2022 16:16:19 -0800 Subject: [PATCH 21/31] pass a bool to let the diagnostic service filter out compiler diagnostics --- .../Helpers/MockDiagnosticAnalyzerService.cs | 2 +- .../Diagnostics/IDiagnosticAnalyzerService.cs | 4 ++-- .../CodeCleanup/AbstractCodeCleanupService.cs | 18 ++---------------- .../Features/CodeFixes/CodeFixService.cs | 2 +- .../Diagnostics/DiagnosticAnalyzerService.cs | 7 ++++--- ...ncrementalAnalyzer_GetDiagnosticsForSpan.cs | 16 +++++++++++----- .../ExternalDiagnosticUpdateSourceTests.vb | 2 +- 7 files changed, 22 insertions(+), 29 deletions(-) diff --git a/src/EditorFeatures/Test/EditAndContinue/Helpers/MockDiagnosticAnalyzerService.cs b/src/EditorFeatures/Test/EditAndContinue/Helpers/MockDiagnosticAnalyzerService.cs index f97caae14eb28..35edf4b6ce30a 100644 --- a/src/EditorFeatures/Test/EditAndContinue/Helpers/MockDiagnosticAnalyzerService.cs +++ b/src/EditorFeatures/Test/EditAndContinue/Helpers/MockDiagnosticAnalyzerService.cs @@ -47,7 +47,7 @@ public Task> GetDiagnosticsAsync(Solution solutio public Task> GetDiagnosticsForIdsAsync(Solution solution, ProjectId? projectId = null, DocumentId? documentId = null, ImmutableHashSet? diagnosticIds = null, bool includeSuppressedDiagnostics = false, CancellationToken cancellationToken = default) => throw new NotImplementedException(); - public Task> GetDiagnosticsForSpanAsync(Document document, TextSpan? range, Func? shouldIncludeDiagnostic, bool includeSuppressedDiagnostics = false, CodeActionRequestPriority priority = CodeActionRequestPriority.None, Func? addOperationScope = null, CancellationToken cancellationToken = default) + public Task> GetDiagnosticsForSpanAsync(Document document, TextSpan? range, Func? shouldIncludeDiagnostic, bool includeSuppressedDiagnostics = false, bool includeCompilerDiagnostics = true, CodeActionRequestPriority priority = CodeActionRequestPriority.None, Func? addOperationScope = null, CancellationToken cancellationToken = default) => throw new NotImplementedException(); public Task> GetProjectDiagnosticsForIdsAsync(Solution solution, ProjectId? projectId = null, ImmutableHashSet? diagnosticIds = null, bool includeSuppressedDiagnostics = false, CancellationToken cancellationToken = default) diff --git a/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs b/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs index 61650e84b54c0..72d1098598538 100644 --- a/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs +++ b/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs @@ -88,7 +88,7 @@ internal interface IDiagnosticAnalyzerService /// none of its reported diagnostics should be included in the result. /// /// - Task> GetDiagnosticsForSpanAsync(Document document, TextSpan? range, Func? shouldIncludeDiagnostic, bool includeSuppressedDiagnostics = false, CodeActionRequestPriority priority = CodeActionRequestPriority.None, Func? addOperationScope = null, CancellationToken cancellationToken = default); + Task> GetDiagnosticsForSpanAsync(Document document, TextSpan? range, Func? shouldIncludeDiagnostic, bool includeSuppressedDiagnostics = false, bool includeCompilerDiagnostics = true, CodeActionRequestPriority priority = CodeActionRequestPriority.None, Func? addOperationScope = null, CancellationToken cancellationToken = default); } internal static class IDiagnosticAnalyzerServiceExtensions @@ -108,7 +108,7 @@ public static Task> GetDiagnosticsForSpanAsync(th { Func? shouldIncludeDiagnostic = diagnosticId != null ? id => id == diagnosticId : null; return service.GetDiagnosticsForSpanAsync(document, range, shouldIncludeDiagnostic, - includeSuppressedDiagnostics, priority, addOperationScope, cancellationToken); + includeSuppressedDiagnostics, true, priority, addOperationScope, cancellationToken); } } } diff --git a/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs b/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs index 1a4fe274679f5..9fc38b6367d8f 100644 --- a/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs +++ b/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs @@ -189,7 +189,8 @@ private async Task ApplyCodeFixesForSpecificDiagnosticIdAsync(Document // Compute diagnostics for everything that is not an IDE analyzer var diagnostics = (await _diagnosticService.GetDiagnosticsForSpanAsync(document, range, - shouldIncludeDiagnostic: static diagnosticId => !(IDEDiagnosticIdToOptionMappingHelper.IsKnownIDEDiagnosticId(diagnosticId) || IsCompilerDiagnostic(diagnosticId)), + shouldIncludeDiagnostic: static diagnosticId => !(IDEDiagnosticIdToOptionMappingHelper.IsKnownIDEDiagnosticId(diagnosticId)), + includeCompilerDiagnostics: false, includeSuppressedDiagnostics: false, cancellationToken: cancellationToken).ConfigureAwait(false)); @@ -200,21 +201,6 @@ private async Task ApplyCodeFixesForSpecificDiagnosticIdAsync(Document } return diagnostics.SelectAsArray(static d => (d.Id, d.Title)).Distinct(); - - static bool IsCompilerDiagnostic(string errorId) - { - if (!string.IsNullOrEmpty(errorId) && errorId.Length > 2) - { - var prefix = errorId[..2]; - if (prefix.Equals("CS", StringComparison.OrdinalIgnoreCase) || prefix.Equals("BC", StringComparison.OrdinalIgnoreCase)) - { - var suffix = errorId[2..]; - return int.TryParse(suffix, out _); - } - } - - return false; - } } private async Task ApplyThirdPartyCodeFixesAsync( diff --git a/src/Features/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs b/src/Features/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs index 4299b47b1688e..ab647d4daa051 100644 --- a/src/Features/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs +++ b/src/Features/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs @@ -173,7 +173,7 @@ public async IAsyncEnumerable StreamFixesAsync( var diagnostics = await _diagnosticService.GetDiagnosticsForSpanAsync( document, range, GetShouldIncludeDiagnosticPredicate(document, priority), - includeSuppressionFixes, priority, addOperationScope, cancellationToken).ConfigureAwait(false); + includeSuppressionFixes, true, priority, addOperationScope, cancellationToken).ConfigureAwait(false); if (diagnostics.IsEmpty) yield break; diff --git a/src/Features/LanguageServer/Protocol/Features/Diagnostics/DiagnosticAnalyzerService.cs b/src/Features/LanguageServer/Protocol/Features/Diagnostics/DiagnosticAnalyzerService.cs index d4e9a1b32e100..44b31ae33a530 100644 --- a/src/Features/LanguageServer/Protocol/Features/Diagnostics/DiagnosticAnalyzerService.cs +++ b/src/Features/LanguageServer/Protocol/Features/Diagnostics/DiagnosticAnalyzerService.cs @@ -83,7 +83,7 @@ public void Reanalyze(Workspace workspace, IEnumerable? projectIds = using var _ = ArrayBuilder.GetInstance(out var diagnostics); var upToDate = await analyzer.TryAppendDiagnosticsForSpanAsync( document, range, diagnostics, shouldIncludeDiagnostic, - includeSuppressedDiagnostics, priority, blockForData: false, + includeSuppressedDiagnostics, true, priority, blockForData: false, addOperationScope: null, cancellationToken).ConfigureAwait(false); return (diagnostics.ToImmutable(), upToDate); }, cancellationToken); @@ -97,6 +97,7 @@ public Task> GetDiagnosticsForSpanAsync( TextSpan? range, Func? shouldIncludeDiagnostic, bool includeSuppressedDiagnostics, + bool includeCompilerDiagnostics, CodeActionRequestPriority priority, Func? addOperationScope, CancellationToken cancellationToken) @@ -105,8 +106,8 @@ public Task> GetDiagnosticsForSpanAsync( { // always make sure that analyzer is called on background thread. return Task.Run(() => analyzer.GetDiagnosticsForSpanAsync( - document, range, shouldIncludeDiagnostic, includeSuppressedDiagnostics, priority, - blockForData: true, addOperationScope, cancellationToken), cancellationToken); + document, range, shouldIncludeDiagnostic, includeSuppressedDiagnostics, includeCompilerDiagnostics, + priority, blockForData: true, addOperationScope, cancellationToken), cancellationToken); } return SpecializedTasks.EmptyImmutableArray(); diff --git a/src/Features/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_GetDiagnosticsForSpan.cs b/src/Features/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_GetDiagnosticsForSpan.cs index dff2ea6da5a2f..0c04872b5f8a1 100644 --- a/src/Features/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_GetDiagnosticsForSpan.cs +++ b/src/Features/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_GetDiagnosticsForSpan.cs @@ -22,11 +22,11 @@ internal partial class DiagnosticIncrementalAnalyzer { public async Task TryAppendDiagnosticsForSpanAsync( Document document, TextSpan? range, ArrayBuilder result, Func? shouldIncludeDiagnostic, - bool includeSuppressedDiagnostics, CodeActionRequestPriority priority, bool blockForData, + bool includeSuppressedDiagnostics, bool includeCompilerDiagnostics, CodeActionRequestPriority priority, bool blockForData, Func? addOperationScope, CancellationToken cancellationToken) { var getter = await LatestDiagnosticsForSpanGetter.CreateAsync( - this, document, range, blockForData, addOperationScope, includeSuppressedDiagnostics, + this, document, range, blockForData, addOperationScope, includeSuppressedDiagnostics, includeCompilerDiagnostics, priority, shouldIncludeDiagnostic, cancellationToken).ConfigureAwait(false); return await getter.TryGetAsync(result, cancellationToken).ConfigureAwait(false); } @@ -36,6 +36,7 @@ public async Task> GetDiagnosticsForSpanAsync( TextSpan? range, Func? shouldIncludeDiagnostic, bool includeSuppressedDiagnostics, + bool includeCompilerDiagnostics, CodeActionRequestPriority priority, bool blockForData, Func? addOperationScope, @@ -43,7 +44,7 @@ public async Task> GetDiagnosticsForSpanAsync( { using var _ = ArrayBuilder.GetInstance(out var list); var result = await TryAppendDiagnosticsForSpanAsync( - document, range, list, shouldIncludeDiagnostic, includeSuppressedDiagnostics, + document, range, list, shouldIncludeDiagnostic, includeSuppressedDiagnostics, includeCompilerDiagnostics, priority, blockForData, addOperationScope, cancellationToken).ConfigureAwait(false); Debug.Assert(result); return list.ToImmutable(); @@ -70,6 +71,7 @@ private sealed class LatestDiagnosticsForSpanGetter private readonly bool _includeSuppressedDiagnostics; private readonly CodeActionRequestPriority _priority; private readonly Func? _shouldIncludeDiagnostic; + private readonly bool _includeCompilerDiagnostics; private readonly Func? _addOperationScope; private delegate Task> DiagnosticsGetterAsync(DiagnosticAnalyzer analyzer, DocumentAnalysisExecutor executor, CancellationToken cancellationToken); @@ -81,6 +83,7 @@ public static async Task CreateAsync( bool blockForData, Func? addOperationScope, bool includeSuppressedDiagnostics, + bool includeCompilerDiagnostics, CodeActionRequestPriority priority, Func? shouldIncludeDiagnostic, CancellationToken cancellationToken) @@ -93,8 +96,8 @@ public static async Task CreateAsync( var compilationWithAnalyzers = await GetOrCreateCompilationWithAnalyzersAsync(document.Project, ideOptions, stateSets, includeSuppressedDiagnostics, cancellationToken).ConfigureAwait(false); return new LatestDiagnosticsForSpanGetter( - owner, compilationWithAnalyzers, document, stateSets, shouldIncludeDiagnostic, range, - blockForData, addOperationScope, includeSuppressedDiagnostics, priority); + owner, compilationWithAnalyzers, document, stateSets, shouldIncludeDiagnostic, includeCompilerDiagnostics, + range, blockForData, addOperationScope, includeSuppressedDiagnostics, priority); } private static async Task GetOrCreateCompilationWithAnalyzersAsync( @@ -129,6 +132,7 @@ private LatestDiagnosticsForSpanGetter( Document document, IEnumerable stateSets, Func? shouldIncludeDiagnostic, + bool includeCompilerDiagnostics, TextSpan? range, bool blockForData, Func? addOperationScope, @@ -140,6 +144,7 @@ private LatestDiagnosticsForSpanGetter( _document = document; _stateSets = stateSets; _shouldIncludeDiagnostic = shouldIncludeDiagnostic; + _includeCompilerDiagnostics = includeCompilerDiagnostics; _range = range; _blockForData = blockForData; _addOperationScope = addOperationScope; @@ -318,6 +323,7 @@ private bool ShouldInclude(DiagnosticData diagnostic) return diagnostic.DocumentId == _document.Id && (_range == null || _range.Value.IntersectsWith(diagnostic.GetTextSpan())) && (_includeSuppressedDiagnostics || !diagnostic.IsSuppressed) + && (_includeCompilerDiagnostics || !diagnostic.CustomTags.Any(static t => t is WellKnownDiagnosticTags.Compiler)) && (_shouldIncludeDiagnostic == null || _shouldIncludeDiagnostic(diagnostic.Id)); } } diff --git a/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb b/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb index 4482ad3bc2698..58e3c715b1566 100644 --- a/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb +++ b/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb @@ -521,7 +521,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Diagnostics Public Sub Reanalyze(workspace As Workspace, Optional projectIds As IEnumerable(Of ProjectId) = Nothing, Optional documentIds As IEnumerable(Of DocumentId) = Nothing, Optional highPriority As Boolean = False) Implements IDiagnosticAnalyzerService.Reanalyze End Sub - Public Function GetDiagnosticsForSpanAsync(document As Document, range As TextSpan?, shouldIncludeDiagnostic As Func(Of String, Boolean), Optional includeSuppressedDiagnostics As Boolean = False, Optional priority As CodeActionRequestPriority = CodeActionRequestPriority.None, Optional addOperationScope As Func(Of String, IDisposable) = Nothing, Optional cancellationToken As CancellationToken = Nothing) As Task(Of ImmutableArray(Of DiagnosticData)) Implements IDiagnosticAnalyzerService.GetDiagnosticsForSpanAsync + Public Function GetDiagnosticsForSpanAsync(document As Document, range As TextSpan?, shouldIncludeDiagnostic As Func(Of String, Boolean), Optional includeSuppressedDiagnostics As Boolean = False, Optional includeCompilerDiagnostics As Boolean = True, Optional priority As CodeActionRequestPriority = CodeActionRequestPriority.None, Optional addOperationScope As Func(Of String, IDisposable) = Nothing, Optional cancellationToken As CancellationToken = Nothing) As Task(Of ImmutableArray(Of DiagnosticData)) Implements IDiagnosticAnalyzerService.GetDiagnosticsForSpanAsync Return SpecializedTasks.EmptyImmutableArray(Of DiagnosticData) End Function From 5a1740a79757a0a8bbcc8cf70ee93266dae608cf Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Mon, 7 Mar 2022 11:16:41 -0800 Subject: [PATCH 22/31] do not make includeCompilerDiagnostics optional --- .../Helpers/MockDiagnosticAnalyzerService.cs | 2 +- .../Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs | 6 +++--- .../Features/CodeCleanup/AbstractCodeCleanupService.cs | 3 +-- .../Features/Diagnostics/DiagnosticAnalyzerService.cs | 2 +- .../Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb | 2 +- 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/EditorFeatures/Test/EditAndContinue/Helpers/MockDiagnosticAnalyzerService.cs b/src/EditorFeatures/Test/EditAndContinue/Helpers/MockDiagnosticAnalyzerService.cs index 35edf4b6ce30a..bf4affae92cd9 100644 --- a/src/EditorFeatures/Test/EditAndContinue/Helpers/MockDiagnosticAnalyzerService.cs +++ b/src/EditorFeatures/Test/EditAndContinue/Helpers/MockDiagnosticAnalyzerService.cs @@ -47,7 +47,7 @@ public Task> GetDiagnosticsAsync(Solution solutio public Task> GetDiagnosticsForIdsAsync(Solution solution, ProjectId? projectId = null, DocumentId? documentId = null, ImmutableHashSet? diagnosticIds = null, bool includeSuppressedDiagnostics = false, CancellationToken cancellationToken = default) => throw new NotImplementedException(); - public Task> GetDiagnosticsForSpanAsync(Document document, TextSpan? range, Func? shouldIncludeDiagnostic, bool includeSuppressedDiagnostics = false, bool includeCompilerDiagnostics = true, CodeActionRequestPriority priority = CodeActionRequestPriority.None, Func? addOperationScope = null, CancellationToken cancellationToken = default) + public Task> GetDiagnosticsForSpanAsync(Document document, TextSpan? range, Func? shouldIncludeDiagnostic, bool includeCompilerDiagnostics, bool includeSuppressedDiagnostics = true, CodeActionRequestPriority priority = CodeActionRequestPriority.None, Func? addOperationScope = null, CancellationToken cancellationToken = default) => throw new NotImplementedException(); public Task> GetProjectDiagnosticsForIdsAsync(Solution solution, ProjectId? projectId = null, ImmutableHashSet? diagnosticIds = null, bool includeSuppressedDiagnostics = false, CancellationToken cancellationToken = default) diff --git a/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs b/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs index 72d1098598538..a80e5cf6061bb 100644 --- a/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs +++ b/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs @@ -75,7 +75,7 @@ internal interface IDiagnosticAnalyzerService /// This API will only force complete analyzers that support span based analysis, i.e. compiler analyzer and /// s that support . /// For the rest of the analyzers, it will only return diagnostics if the analyzer has already been executed. - /// Use + /// Use /// if you want to force complete all analyzers and get up-to-date diagnostics for all analyzers for the given span. /// Task<(ImmutableArray diagnostics, bool upToDate)> TryGetDiagnosticsForSpanAsync(Document document, TextSpan range, Func? shouldIncludeDiagnostic, bool includeSuppressedDiagnostics = false, CodeActionRequestPriority priority = CodeActionRequestPriority.None, CancellationToken cancellationToken = default); @@ -88,7 +88,7 @@ internal interface IDiagnosticAnalyzerService /// none of its reported diagnostics should be included in the result. /// /// - Task> GetDiagnosticsForSpanAsync(Document document, TextSpan? range, Func? shouldIncludeDiagnostic, bool includeSuppressedDiagnostics = false, bool includeCompilerDiagnostics = true, CodeActionRequestPriority priority = CodeActionRequestPriority.None, Func? addOperationScope = null, CancellationToken cancellationToken = default); + Task> GetDiagnosticsForSpanAsync(Document document, TextSpan? range, Func? shouldIncludeDiagnostic, bool includeCompilerDiagnostics, bool includeSuppressedDiagnostics = false, CodeActionRequestPriority priority = CodeActionRequestPriority.None, Func? addOperationScope = null, CancellationToken cancellationToken = default); } internal static class IDiagnosticAnalyzerServiceExtensions @@ -108,7 +108,7 @@ public static Task> GetDiagnosticsForSpanAsync(th { Func? shouldIncludeDiagnostic = diagnosticId != null ? id => id == diagnosticId : null; return service.GetDiagnosticsForSpanAsync(document, range, shouldIncludeDiagnostic, - includeSuppressedDiagnostics, true, priority, addOperationScope, cancellationToken); + includeCompilerDiagnostics: true, includeSuppressedDiagnostics: true, priority: priority, addOperationScope: addOperationScope, cancellationToken: cancellationToken); } } } diff --git a/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs b/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs index 9fc38b6367d8f..2d2d57a781c92 100644 --- a/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs +++ b/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs @@ -190,8 +190,7 @@ private async Task ApplyCodeFixesForSpecificDiagnosticIdAsync(Document // Compute diagnostics for everything that is not an IDE analyzer var diagnostics = (await _diagnosticService.GetDiagnosticsForSpanAsync(document, range, shouldIncludeDiagnostic: static diagnosticId => !(IDEDiagnosticIdToOptionMappingHelper.IsKnownIDEDiagnosticId(diagnosticId)), - includeCompilerDiagnostics: false, - includeSuppressedDiagnostics: false, + includeCompilerDiagnostics: true, includeSuppressedDiagnostics: false, cancellationToken: cancellationToken).ConfigureAwait(false)); // ensure more than just known diagnostics were returned diff --git a/src/Features/LanguageServer/Protocol/Features/Diagnostics/DiagnosticAnalyzerService.cs b/src/Features/LanguageServer/Protocol/Features/Diagnostics/DiagnosticAnalyzerService.cs index 44b31ae33a530..b447b8757f2e0 100644 --- a/src/Features/LanguageServer/Protocol/Features/Diagnostics/DiagnosticAnalyzerService.cs +++ b/src/Features/LanguageServer/Protocol/Features/Diagnostics/DiagnosticAnalyzerService.cs @@ -96,8 +96,8 @@ public Task> GetDiagnosticsForSpanAsync( Document document, TextSpan? range, Func? shouldIncludeDiagnostic, - bool includeSuppressedDiagnostics, bool includeCompilerDiagnostics, + bool includeSuppressedDiagnostics, CodeActionRequestPriority priority, Func? addOperationScope, CancellationToken cancellationToken) diff --git a/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb b/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb index 58e3c715b1566..bdc17af3f8604 100644 --- a/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb +++ b/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb @@ -521,7 +521,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Diagnostics Public Sub Reanalyze(workspace As Workspace, Optional projectIds As IEnumerable(Of ProjectId) = Nothing, Optional documentIds As IEnumerable(Of DocumentId) = Nothing, Optional highPriority As Boolean = False) Implements IDiagnosticAnalyzerService.Reanalyze End Sub - Public Function GetDiagnosticsForSpanAsync(document As Document, range As TextSpan?, shouldIncludeDiagnostic As Func(Of String, Boolean), Optional includeSuppressedDiagnostics As Boolean = False, Optional includeCompilerDiagnostics As Boolean = True, Optional priority As CodeActionRequestPriority = CodeActionRequestPriority.None, Optional addOperationScope As Func(Of String, IDisposable) = Nothing, Optional cancellationToken As CancellationToken = Nothing) As Task(Of ImmutableArray(Of DiagnosticData)) Implements IDiagnosticAnalyzerService.GetDiagnosticsForSpanAsync + Public Function GetDiagnosticsForSpanAsync(document As Document, range As TextSpan?, shouldIncludeDiagnostic As Func(Of String, Boolean), includeCompilerDiagnostics As Boolean, Optional includeSuppressedDiagnostics As Boolean = False, Optional priority As CodeActionRequestPriority = CodeActionRequestPriority.None, Optional addOperationScope As Func(Of String, IDisposable) = Nothing, Optional cancellationToken As CancellationToken = Nothing) As Task(Of ImmutableArray(Of DiagnosticData)) Implements IDiagnosticAnalyzerService.GetDiagnosticsForSpanAsync Return SpecializedTasks.EmptyImmutableArray(Of DiagnosticData) End Function From 777d07345e19ee2f3b2273d5d71a5c10949ec56d Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Tue, 15 Mar 2022 13:15:51 -0700 Subject: [PATCH 23/31] change wording to match mikas suggestion --- .../Def/CodeCleanup/CommonCodeCleanUpFixerDiagnosticIds.cs | 2 +- src/VisualStudio/Core/Def/ServicesVSResources.resx | 3 +++ src/VisualStudio/Core/Def/xlf/ServicesVSResources.cs.xlf | 4 ++++ src/VisualStudio/Core/Def/xlf/ServicesVSResources.de.xlf | 4 ++++ src/VisualStudio/Core/Def/xlf/ServicesVSResources.es.xlf | 4 ++++ src/VisualStudio/Core/Def/xlf/ServicesVSResources.fr.xlf | 4 ++++ src/VisualStudio/Core/Def/xlf/ServicesVSResources.it.xlf | 4 ++++ src/VisualStudio/Core/Def/xlf/ServicesVSResources.ja.xlf | 4 ++++ src/VisualStudio/Core/Def/xlf/ServicesVSResources.ko.xlf | 4 ++++ src/VisualStudio/Core/Def/xlf/ServicesVSResources.pl.xlf | 4 ++++ src/VisualStudio/Core/Def/xlf/ServicesVSResources.pt-BR.xlf | 4 ++++ src/VisualStudio/Core/Def/xlf/ServicesVSResources.ru.xlf | 4 ++++ src/VisualStudio/Core/Def/xlf/ServicesVSResources.tr.xlf | 4 ++++ src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hans.xlf | 4 ++++ src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hant.xlf | 4 ++++ 15 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/VisualStudio/Core/Def/CodeCleanup/CommonCodeCleanUpFixerDiagnosticIds.cs b/src/VisualStudio/Core/Def/CodeCleanup/CommonCodeCleanUpFixerDiagnosticIds.cs index 3fe5fcb9bfa12..fa4e6d1d6a2f5 100644 --- a/src/VisualStudio/Core/Def/CodeCleanup/CommonCodeCleanUpFixerDiagnosticIds.cs +++ b/src/VisualStudio/Core/Def/CodeCleanup/CommonCodeCleanUpFixerDiagnosticIds.cs @@ -336,7 +336,7 @@ internal static class CommonCodeCleanUpFixerDiagnosticIds [Order(After = IDEDiagnosticIds.RemoveUnnecessaryCastDiagnosticId)] [ConfigurationKey("unused")] [HelpLink($"https://microsoft.com/")] - [LocalizedName(typeof(ServicesVSResources), nameof(ServicesVSResources.Fix_analyzer_warnings_and_errors))] + [LocalizedName(typeof(ServicesVSResources), nameof(ServicesVSResources.Fix_analyzer_warnings_and_errors_set_in_EditorConfig))] public static readonly FixIdDefinition? ThirdPartyAnalyzers; } } diff --git a/src/VisualStudio/Core/Def/ServicesVSResources.resx b/src/VisualStudio/Core/Def/ServicesVSResources.resx index dfe9f0a6b9153..b8d02bb572773 100644 --- a/src/VisualStudio/Core/Def/ServicesVSResources.resx +++ b/src/VisualStudio/Core/Def/ServicesVSResources.resx @@ -1974,4 +1974,7 @@ Additional information: {1} Fix analyzer warnings and errors + + Fix analyzer warnings and errors set in EditorConfig + \ No newline at end of file diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.cs.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.cs.xlf index 0f6f52c1c8bf9..40e2d95acdbf6 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.cs.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.cs.xlf @@ -470,6 +470,10 @@ Fix analyzer warnings and errors Fix analyzer warnings and errors + + + Fix analyzer warnings and errors set in EditorConfig + Fix analyzer warnings and errors set in EditorConfig diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.de.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.de.xlf index fb6b33c61885f..95faf07587380 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.de.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.de.xlf @@ -470,6 +470,10 @@ Fix analyzer warnings and errors Fix analyzer warnings and errors + + + Fix analyzer warnings and errors set in EditorConfig + Fix analyzer warnings and errors set in EditorConfig diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.es.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.es.xlf index a5e7b1b2f94a9..88ab9fa092992 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.es.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.es.xlf @@ -470,6 +470,10 @@ Fix analyzer warnings and errors Fix analyzer warnings and errors + + + Fix analyzer warnings and errors set in EditorConfig + Fix analyzer warnings and errors set in EditorConfig diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.fr.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.fr.xlf index 1b132d56a36a9..259c8e60abfea 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.fr.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.fr.xlf @@ -470,6 +470,10 @@ Fix analyzer warnings and errors Fix analyzer warnings and errors + + + Fix analyzer warnings and errors set in EditorConfig + Fix analyzer warnings and errors set in EditorConfig diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.it.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.it.xlf index 5ea13551c6aa9..372404d2fdd8a 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.it.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.it.xlf @@ -470,6 +470,10 @@ Fix analyzer warnings and errors Fix analyzer warnings and errors + + + Fix analyzer warnings and errors set in EditorConfig + Fix analyzer warnings and errors set in EditorConfig diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ja.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ja.xlf index 64a264dc15123..746d450355adb 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ja.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ja.xlf @@ -470,6 +470,10 @@ Fix analyzer warnings and errors Fix analyzer warnings and errors + + + Fix analyzer warnings and errors set in EditorConfig + Fix analyzer warnings and errors set in EditorConfig diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ko.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ko.xlf index f89bb14bea98a..10d7d99209be4 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ko.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ko.xlf @@ -470,6 +470,10 @@ Fix analyzer warnings and errors Fix analyzer warnings and errors + + + Fix analyzer warnings and errors set in EditorConfig + Fix analyzer warnings and errors set in EditorConfig diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pl.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pl.xlf index cfdb25735d7ee..131119a4d4f30 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pl.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pl.xlf @@ -470,6 +470,10 @@ Fix analyzer warnings and errors Fix analyzer warnings and errors + + + Fix analyzer warnings and errors set in EditorConfig + Fix analyzer warnings and errors set in EditorConfig diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pt-BR.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pt-BR.xlf index 6efb6bac09688..bd60020faf2bb 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pt-BR.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pt-BR.xlf @@ -470,6 +470,10 @@ Fix analyzer warnings and errors Fix analyzer warnings and errors + + + Fix analyzer warnings and errors set in EditorConfig + Fix analyzer warnings and errors set in EditorConfig diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ru.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ru.xlf index bad27900e129e..3df45251802f0 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ru.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ru.xlf @@ -470,6 +470,10 @@ Fix analyzer warnings and errors Fix analyzer warnings and errors + + + Fix analyzer warnings and errors set in EditorConfig + Fix analyzer warnings and errors set in EditorConfig diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.tr.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.tr.xlf index c8ffa2d44c7ef..2cc12cb446a78 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.tr.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.tr.xlf @@ -470,6 +470,10 @@ Fix analyzer warnings and errors Fix analyzer warnings and errors + + + Fix analyzer warnings and errors set in EditorConfig + Fix analyzer warnings and errors set in EditorConfig diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hans.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hans.xlf index e5c0007bd5a82..f0993cbd1d874 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hans.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hans.xlf @@ -470,6 +470,10 @@ Fix analyzer warnings and errors Fix analyzer warnings and errors + + + Fix analyzer warnings and errors set in EditorConfig + Fix analyzer warnings and errors set in EditorConfig diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hant.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hant.xlf index e900a4da216c5..e2d1c6cae22a9 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hant.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hant.xlf @@ -470,6 +470,10 @@ Fix analyzer warnings and errors Fix analyzer warnings and errors + + + Fix analyzer warnings and errors set in EditorConfig + Fix analyzer warnings and errors set in EditorConfig From dbf67f305958be1968a576ff5378f365f2ee9288 Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Tue, 15 Mar 2022 13:36:04 -0700 Subject: [PATCH 24/31] move the progress reporting to never "rewind" and instead report everything in one list --- .../CodeCleanup/AbstractCodeCleanupService.cs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs b/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs index 2d2d57a781c92..689f67be2946e 100644 --- a/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs +++ b/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs @@ -18,7 +18,6 @@ using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.Utilities; using Microsoft.CodeAnalysis.Text; -using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CodeCleanup { @@ -65,9 +64,20 @@ public async Task CleanupAsync( progressTracker.AddItems(1); } + if (enabledDiagnostics.Diagnostics.Any()) + { + progressTracker.AddItems(enabledDiagnostics.Diagnostics.Length); + } + document = await ApplyCodeFixesAsync( document, enabledDiagnostics.Diagnostics, progressTracker, fallbackOptions, cancellationToken).ConfigureAwait(false); + if (enabledDiagnostics.RunThirdPartyFixers) + { + document = await ApplyThirdPartyCodeFixesAsync( + document, thirdPartyDiagnosticIdsAndTitles, progressTracker, options, cancellationToken).ConfigureAwait(false); + } + // do the remove usings after code fix, as code fix might remove some code which can results in unused usings. if (organizeUsings) { @@ -93,7 +103,6 @@ public async Task CleanupAsync( { document = await ApplyThirdPartyCodeFixesAsync( document, thirdPartyDiagnosticIdsAndTitles, progressTracker, fallbackOptions, cancellationToken).ConfigureAwait(false); - progressTracker.ItemCompleted(); } return document; @@ -130,8 +139,6 @@ private async Task ApplyCodeFixesAsync( IProgressTracker progressTracker, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken) { // Add a progress item for each enabled option we're going to fixup. - progressTracker.AddItems(enabledDiagnosticSets.Length); - foreach (var diagnosticSet in enabledDiagnosticSets) { cancellationToken.ThrowIfCancellationRequested(); @@ -211,6 +218,8 @@ private async Task ApplyThirdPartyCodeFixesAsync( { foreach (var (diagnosticId, title) in diagnosticIds) { + cancellationToken.ThrowIfCancellationRequested(); + progressTracker.Description = string.Format(FeaturesResources.Fixing_0, title ?? diagnosticId); // Apply codefixes for diagnostics with a severity of warning or higher var updatedDocument = await _codeFixService.ApplyCodeFixesForSpecificDiagnosticIdAsync( From 23a0e4dbda25938d84d1c4c8ca7b81538d5652c2 Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Tue, 15 Mar 2022 14:02:25 -0700 Subject: [PATCH 25/31] convert EnabledDiagnosticOptions to a record --- .../CodeCleanup/AbstractCodeCleanupService.cs | 2 +- .../CodeCleanup/EnabledDiagnosticOptions.cs | 17 +---------------- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs b/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs index 689f67be2946e..055fb61f34c00 100644 --- a/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs +++ b/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs @@ -263,6 +263,6 @@ static bool ChangesMadeOutsideDocument(Document currentDocument, Document update } } public EnabledDiagnosticOptions GetAllDiagnostics() - => new EnabledDiagnosticOptions(formatDocument: true, runThirdPartyFixers: true, GetDiagnosticSets(), new OrganizeUsingsSet(isRemoveUnusedImportEnabled: true, isSortImportsEnabled: true)); + => new(FormatDocument: true, RunThirdPartyFixers: true, Diagnostics: GetDiagnosticSets(), OrganizeUsings: new OrganizeUsingsSet(isRemoveUnusedImportEnabled: true, isSortImportsEnabled: true)); } } diff --git a/src/Features/LanguageServer/Protocol/Features/CodeCleanup/EnabledDiagnosticOptions.cs b/src/Features/LanguageServer/Protocol/Features/CodeCleanup/EnabledDiagnosticOptions.cs index 7b89ec5b9f87c..5095d988cace9 100644 --- a/src/Features/LanguageServer/Protocol/Features/CodeCleanup/EnabledDiagnosticOptions.cs +++ b/src/Features/LanguageServer/Protocol/Features/CodeCleanup/EnabledDiagnosticOptions.cs @@ -11,20 +11,5 @@ namespace Microsoft.CodeAnalysis.CodeCleanup /// /// Indicates which features are enabled for a code cleanup operation. /// - internal sealed class EnabledDiagnosticOptions - { - public bool FormatDocument { get; } - public bool RunThirdPartyFixers { get; } - public ImmutableArray Diagnostics { get; } - - public OrganizeUsingsSet OrganizeUsings { get; } - - public EnabledDiagnosticOptions(bool formatDocument, bool runThirdPartyFixers, ImmutableArray diagnostics, OrganizeUsingsSet organizeUsings) - { - FormatDocument = formatDocument; - RunThirdPartyFixers = runThirdPartyFixers; - Diagnostics = diagnostics; - OrganizeUsings = organizeUsings; - } - } + internal sealed record EnabledDiagnosticOptions(bool FormatDocument, bool RunThirdPartyFixers, ImmutableArray Diagnostics, OrganizeUsingsSet OrganizeUsings); } From e41f17660caa3ab6c9a7e79b63b799004b346932 Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Tue, 15 Mar 2022 14:16:51 -0700 Subject: [PATCH 26/31] add a an option that lets you run everything --- .../CodeCleanup/AbstractCodeCleanupService.cs | 2 +- .../CodeCleanup/AbstractCodeCleanUpFixer.cs | 41 ++++++++++--------- .../CommonCodeCleanUpFixerDiagnosticIds.cs | 9 ++++ .../Core/Def/ServicesVSResources.resx | 3 ++ .../Core/Def/xlf/ServicesVSResources.cs.xlf | 6 +++ .../Core/Def/xlf/ServicesVSResources.de.xlf | 6 +++ .../Core/Def/xlf/ServicesVSResources.es.xlf | 6 +++ .../Core/Def/xlf/ServicesVSResources.fr.xlf | 6 +++ .../Core/Def/xlf/ServicesVSResources.it.xlf | 6 +++ .../Core/Def/xlf/ServicesVSResources.ja.xlf | 6 +++ .../Core/Def/xlf/ServicesVSResources.ko.xlf | 6 +++ .../Core/Def/xlf/ServicesVSResources.pl.xlf | 6 +++ .../Def/xlf/ServicesVSResources.pt-BR.xlf | 6 +++ .../Core/Def/xlf/ServicesVSResources.ru.xlf | 6 +++ .../Core/Def/xlf/ServicesVSResources.tr.xlf | 6 +++ .../Def/xlf/ServicesVSResources.zh-Hans.xlf | 6 +++ .../Def/xlf/ServicesVSResources.zh-Hant.xlf | 6 +++ 17 files changed, 113 insertions(+), 20 deletions(-) diff --git a/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs b/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs index 055fb61f34c00..77d84a1a2d9a2 100644 --- a/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs +++ b/src/Features/LanguageServer/Protocol/Features/CodeCleanup/AbstractCodeCleanupService.cs @@ -75,7 +75,7 @@ public async Task CleanupAsync( if (enabledDiagnostics.RunThirdPartyFixers) { document = await ApplyThirdPartyCodeFixesAsync( - document, thirdPartyDiagnosticIdsAndTitles, progressTracker, options, cancellationToken).ConfigureAwait(false); + document, thirdPartyDiagnosticIdsAndTitles, progressTracker, fallbackOptions, cancellationToken).ConfigureAwait(false); } // do the remove usings after code fix, as code fix might remove some code which can results in unused usings. diff --git a/src/VisualStudio/Core/Def/CodeCleanup/AbstractCodeCleanUpFixer.cs b/src/VisualStudio/Core/Def/CodeCleanup/AbstractCodeCleanUpFixer.cs index 08929ada3b947..10e2bb57377ca 100644 --- a/src/VisualStudio/Core/Def/CodeCleanup/AbstractCodeCleanUpFixer.cs +++ b/src/VisualStudio/Core/Def/CodeCleanup/AbstractCodeCleanUpFixer.cs @@ -42,6 +42,7 @@ internal abstract class AbstractCodeCleanUpFixer : ICodeCleanUpFixer protected internal const string RemoveUnusedImportsFixId = nameof(RemoveUnusedImportsFixId); protected internal const string SortImportsFixId = nameof(SortImportsFixId); protected internal const string ApplyThirdPartyFixersId = nameof(ApplyThirdPartyFixersId); + protected internal const string ApplyAllAnalyzerFixersId = nameof(ApplyAllAnalyzerFixersId); private readonly IThreadingContext _threadingContext; private readonly VisualStudioWorkspaceImpl _workspace; @@ -329,31 +330,33 @@ private static async Task FixDocumentAsync( var codeCleanupService = document.GetRequiredLanguageService(); - var allDiagnostics = codeCleanupService.GetAllDiagnostics(); - - var enabedDiagnosticSets = ArrayBuilder.GetInstance(); - - foreach (var diagnostic in allDiagnostics.Diagnostics) + var enabledDiagnostics = codeCleanupService.GetAllDiagnostics(); + if (!enabledFixIds.IsFixIdEnabled(ApplyAllAnalyzerFixersId)) { - foreach (var diagnosticId in diagnostic.DiagnosticIds) + var enabedDiagnosticSets = ArrayBuilder.GetInstance(); + + foreach (var diagnostic in enabledDiagnostics.Diagnostics) { - if (enabledFixIds.IsFixIdEnabled(diagnosticId)) + foreach (var diagnosticId in diagnostic.DiagnosticIds) { - enabedDiagnosticSets.Add(diagnostic); - break; + if (enabledFixIds.IsFixIdEnabled(diagnosticId)) + { + enabedDiagnosticSets.Add(diagnostic); + break; + } } } - } - var isFormatDocumentEnabled = enabledFixIds.IsFixIdEnabled(FormatDocumentFixId); - var isRemoveUnusedUsingsEnabled = enabledFixIds.IsFixIdEnabled(RemoveUnusedImportsFixId); - var isSortUsingsEnabled = enabledFixIds.IsFixIdEnabled(SortImportsFixId); - var isApplyThirdPartyFixersEnabled = enabledFixIds.IsFixIdEnabled(ApplyThirdPartyFixersId); - var enabledDiagnostics = new EnabledDiagnosticOptions( - isFormatDocumentEnabled, - isApplyThirdPartyFixersEnabled, - enabedDiagnosticSets.ToImmutableArray(), - new OrganizeUsingsSet(isRemoveUnusedUsingsEnabled, isSortUsingsEnabled)); + var isFormatDocumentEnabled = enabledFixIds.IsFixIdEnabled(FormatDocumentFixId); + var isRemoveUnusedUsingsEnabled = enabledFixIds.IsFixIdEnabled(RemoveUnusedImportsFixId); + var isSortUsingsEnabled = enabledFixIds.IsFixIdEnabled(SortImportsFixId); + var isApplyThirdPartyFixersEnabled = enabledFixIds.IsFixIdEnabled(ApplyThirdPartyFixersId); + enabledDiagnostics = new EnabledDiagnosticOptions( + isFormatDocumentEnabled, + isApplyThirdPartyFixersEnabled, + enabedDiagnosticSets.ToImmutableArray(), + new OrganizeUsingsSet(isRemoveUnusedUsingsEnabled, isSortUsingsEnabled)); + } return await codeCleanupService.CleanupAsync( document, enabledDiagnostics, progressTracker, ideOptions.CreateProvider(), cancellationToken).ConfigureAwait(false); diff --git a/src/VisualStudio/Core/Def/CodeCleanup/CommonCodeCleanUpFixerDiagnosticIds.cs b/src/VisualStudio/Core/Def/CodeCleanup/CommonCodeCleanUpFixerDiagnosticIds.cs index fa4e6d1d6a2f5..b5f9c55fbb18f 100644 --- a/src/VisualStudio/Core/Def/CodeCleanup/CommonCodeCleanUpFixerDiagnosticIds.cs +++ b/src/VisualStudio/Core/Def/CodeCleanup/CommonCodeCleanUpFixerDiagnosticIds.cs @@ -338,5 +338,14 @@ internal static class CommonCodeCleanUpFixerDiagnosticIds [HelpLink($"https://microsoft.com/")] [LocalizedName(typeof(ServicesVSResources), nameof(ServicesVSResources.Fix_analyzer_warnings_and_errors_set_in_EditorConfig))] public static readonly FixIdDefinition? ThirdPartyAnalyzers; + + [Export] + [FixId(AbstractCodeCleanUpFixer.ApplyAllAnalyzerFixersId)] + [Name(AbstractCodeCleanUpFixer.ApplyAllAnalyzerFixersId)] + [Order(After = IDEDiagnosticIds.RemoveUnnecessaryCastDiagnosticId)] + [ConfigurationKey("unused")] + [HelpLink($"https://microsoft.com/")] + [LocalizedName(typeof(ServicesVSResources), nameof(ServicesVSResources.Fix_all_warnings_and_errors_set_in_EditorConfig))] + public static readonly FixIdDefinition? AllAnalyzers; } } diff --git a/src/VisualStudio/Core/Def/ServicesVSResources.resx b/src/VisualStudio/Core/Def/ServicesVSResources.resx index b8d02bb572773..676a0e893ee18 100644 --- a/src/VisualStudio/Core/Def/ServicesVSResources.resx +++ b/src/VisualStudio/Core/Def/ServicesVSResources.resx @@ -1977,4 +1977,7 @@ Additional information: {1} Fix analyzer warnings and errors set in EditorConfig + + Fix all warnings and errors set in EditorConfig + \ No newline at end of file diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.cs.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.cs.xlf index 40e2d95acdbf6..410fc4135d3d9 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.cs.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.cs.xlf @@ -470,6 +470,12 @@ Fix analyzer warnings and errors Fix analyzer warnings and errors + + + + Fix all warnings and errors set in EditorConfig + Fix all warnings and errors set in EditorConfig + Fix analyzer warnings and errors set in EditorConfig diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.de.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.de.xlf index 95faf07587380..2a98139ada8c0 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.de.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.de.xlf @@ -470,6 +470,12 @@ Fix analyzer warnings and errors Fix analyzer warnings and errors + + + + Fix all warnings and errors set in EditorConfig + Fix all warnings and errors set in EditorConfig + Fix analyzer warnings and errors set in EditorConfig diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.es.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.es.xlf index 88ab9fa092992..965071375c21e 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.es.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.es.xlf @@ -470,6 +470,12 @@ Fix analyzer warnings and errors Fix analyzer warnings and errors + + + + Fix all warnings and errors set in EditorConfig + Fix all warnings and errors set in EditorConfig + Fix analyzer warnings and errors set in EditorConfig diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.fr.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.fr.xlf index 259c8e60abfea..783310dcf401d 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.fr.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.fr.xlf @@ -470,6 +470,12 @@ Fix analyzer warnings and errors Fix analyzer warnings and errors + + + + Fix all warnings and errors set in EditorConfig + Fix all warnings and errors set in EditorConfig + Fix analyzer warnings and errors set in EditorConfig diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.it.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.it.xlf index 372404d2fdd8a..4ca13ac893c04 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.it.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.it.xlf @@ -470,6 +470,12 @@ Fix analyzer warnings and errors Fix analyzer warnings and errors + + + + Fix all warnings and errors set in EditorConfig + Fix all warnings and errors set in EditorConfig + Fix analyzer warnings and errors set in EditorConfig diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ja.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ja.xlf index 746d450355adb..8f3b4b755a72e 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ja.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ja.xlf @@ -470,6 +470,12 @@ Fix analyzer warnings and errors Fix analyzer warnings and errors + + + + Fix all warnings and errors set in EditorConfig + Fix all warnings and errors set in EditorConfig + Fix analyzer warnings and errors set in EditorConfig diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ko.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ko.xlf index 10d7d99209be4..b9ec52597d46d 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ko.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ko.xlf @@ -470,6 +470,12 @@ Fix analyzer warnings and errors Fix analyzer warnings and errors + + + + Fix all warnings and errors set in EditorConfig + Fix all warnings and errors set in EditorConfig + Fix analyzer warnings and errors set in EditorConfig diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pl.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pl.xlf index 131119a4d4f30..87afaf4d8b910 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pl.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pl.xlf @@ -470,6 +470,12 @@ Fix analyzer warnings and errors Fix analyzer warnings and errors + + + + Fix all warnings and errors set in EditorConfig + Fix all warnings and errors set in EditorConfig + Fix analyzer warnings and errors set in EditorConfig diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pt-BR.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pt-BR.xlf index bd60020faf2bb..37c000891e839 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pt-BR.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pt-BR.xlf @@ -470,6 +470,12 @@ Fix analyzer warnings and errors Fix analyzer warnings and errors + + + + Fix all warnings and errors set in EditorConfig + Fix all warnings and errors set in EditorConfig + Fix analyzer warnings and errors set in EditorConfig diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ru.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ru.xlf index 3df45251802f0..c63b64eea36bf 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ru.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ru.xlf @@ -470,6 +470,12 @@ Fix analyzer warnings and errors Fix analyzer warnings and errors + + + + Fix all warnings and errors set in EditorConfig + Fix all warnings and errors set in EditorConfig + Fix analyzer warnings and errors set in EditorConfig diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.tr.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.tr.xlf index 2cc12cb446a78..56e3f32caadb1 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.tr.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.tr.xlf @@ -470,6 +470,12 @@ Fix analyzer warnings and errors Fix analyzer warnings and errors + + + + Fix all warnings and errors set in EditorConfig + Fix all warnings and errors set in EditorConfig + Fix analyzer warnings and errors set in EditorConfig diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hans.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hans.xlf index f0993cbd1d874..96da70c75caa3 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hans.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hans.xlf @@ -470,6 +470,12 @@ Fix analyzer warnings and errors Fix analyzer warnings and errors + + + + Fix all warnings and errors set in EditorConfig + Fix all warnings and errors set in EditorConfig + Fix analyzer warnings and errors set in EditorConfig diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hant.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hant.xlf index e2d1c6cae22a9..8ce90f5612f28 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hant.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hant.xlf @@ -470,6 +470,12 @@ Fix analyzer warnings and errors Fix analyzer warnings and errors + + + + Fix all warnings and errors set in EditorConfig + Fix all warnings and errors set in EditorConfig + Fix analyzer warnings and errors set in EditorConfig From 73f608ade84b1387f1c438e5bbda0e85f4170c4b Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Tue, 7 Jun 2022 14:45:47 -0700 Subject: [PATCH 27/31] pass parameter through to service --- .../Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs b/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs index a80e5cf6061bb..6db2371f1087a 100644 --- a/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs +++ b/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs @@ -108,7 +108,7 @@ public static Task> GetDiagnosticsForSpanAsync(th { Func? shouldIncludeDiagnostic = diagnosticId != null ? id => id == diagnosticId : null; return service.GetDiagnosticsForSpanAsync(document, range, shouldIncludeDiagnostic, - includeCompilerDiagnostics: true, includeSuppressedDiagnostics: true, priority: priority, addOperationScope: addOperationScope, cancellationToken: cancellationToken); + includeCompilerDiagnostics: true, includeSuppressedDiagnostics, priority: priority, addOperationScope: addOperationScope, cancellationToken: cancellationToken); } } } From c8941d590460ae57e0ec20f4d85d3e707cbbc792 Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Tue, 7 Jun 2022 17:43:49 -0700 Subject: [PATCH 28/31] fixup test (unnecessary async keyword is now removed) --- src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs b/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs index b0a219f6cf895..a8c1fc1fc01bc 100644 --- a/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs +++ b/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs @@ -109,7 +109,7 @@ public Task SortGlobalUsings() global using System; class Program { - static async Task Main(string[] args) + static Task Main(string[] args) { Barrier b = new Barrier(0); var list = new List(); @@ -126,7 +126,7 @@ static async Task Main(string[] args) internal class Program { - private static async Task Main(string[] args) + private static Task Main(string[] args) { Barrier b = new(0); List list = new(); From bf9c6904be1e588072ebc0e77acdbcd609e59c58 Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Mon, 13 Jun 2022 18:12:11 -0700 Subject: [PATCH 29/31] Update src/VisualStudio/Core/Def/CodeCleanup/AbstractCodeCleanUpFixer.cs Co-authored-by: Andrew Hall --- .../Core/Def/CodeCleanup/AbstractCodeCleanUpFixer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/VisualStudio/Core/Def/CodeCleanup/AbstractCodeCleanUpFixer.cs b/src/VisualStudio/Core/Def/CodeCleanup/AbstractCodeCleanUpFixer.cs index 10e2bb57377ca..34a72c8688533 100644 --- a/src/VisualStudio/Core/Def/CodeCleanup/AbstractCodeCleanUpFixer.cs +++ b/src/VisualStudio/Core/Def/CodeCleanup/AbstractCodeCleanUpFixer.cs @@ -333,7 +333,7 @@ private static async Task FixDocumentAsync( var enabledDiagnostics = codeCleanupService.GetAllDiagnostics(); if (!enabledFixIds.IsFixIdEnabled(ApplyAllAnalyzerFixersId)) { - var enabedDiagnosticSets = ArrayBuilder.GetInstance(); + var enabledDiagnosticSets = ArrayBuilder.GetInstance(); foreach (var diagnostic in enabledDiagnostics.Diagnostics) { From 04cf0c8dd9be426f367dfaaaa0cdcef49037c0b8 Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Mon, 13 Jun 2022 20:43:02 -0700 Subject: [PATCH 30/31] fixup variable rename --- .../Core/Def/CodeCleanup/AbstractCodeCleanUpFixer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/VisualStudio/Core/Def/CodeCleanup/AbstractCodeCleanUpFixer.cs b/src/VisualStudio/Core/Def/CodeCleanup/AbstractCodeCleanUpFixer.cs index 34a72c8688533..dbd9eacf9bc56 100644 --- a/src/VisualStudio/Core/Def/CodeCleanup/AbstractCodeCleanUpFixer.cs +++ b/src/VisualStudio/Core/Def/CodeCleanup/AbstractCodeCleanUpFixer.cs @@ -341,7 +341,7 @@ private static async Task FixDocumentAsync( { if (enabledFixIds.IsFixIdEnabled(diagnosticId)) { - enabedDiagnosticSets.Add(diagnostic); + enabledDiagnosticSets.Add(diagnostic); break; } } @@ -354,7 +354,7 @@ private static async Task FixDocumentAsync( enabledDiagnostics = new EnabledDiagnosticOptions( isFormatDocumentEnabled, isApplyThirdPartyFixersEnabled, - enabedDiagnosticSets.ToImmutableArray(), + enabledDiagnosticSets.ToImmutableArray(), new OrganizeUsingsSet(isRemoveUnusedUsingsEnabled, isSortUsingsEnabled)); } From dff871c733a46b943167ff4ad3e0e978e7c1f2fd Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Mon, 13 Jun 2022 22:29:07 -0700 Subject: [PATCH 31/31] correctly pas arguments so we get compiler diagnostics --- .../Protocol/Features/CodeFixes/CodeFixService.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Features/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs b/src/Features/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs index ab647d4daa051..8506b92f9c976 100644 --- a/src/Features/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs +++ b/src/Features/LanguageServer/Protocol/Features/CodeFixes/CodeFixService.cs @@ -173,7 +173,8 @@ public async IAsyncEnumerable StreamFixesAsync( var diagnostics = await _diagnosticService.GetDiagnosticsForSpanAsync( document, range, GetShouldIncludeDiagnosticPredicate(document, priority), - includeSuppressionFixes, true, priority, addOperationScope, cancellationToken).ConfigureAwait(false); + includeCompilerDiagnostics: true, includeSuppressedDiagnostics: includeSuppressionFixes, priority: priority, + addOperationScope: addOperationScope, cancellationToken: cancellationToken).ConfigureAwait(false); if (diagnostics.IsEmpty) yield break;