From e4c90bb7d675ceedaeee9ee33e1d97d5d4bf60e6 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Wed, 17 Mar 2021 15:31:09 +0000 Subject: [PATCH 001/674] Add accessibility modifier on file creation --- ...ddAccessibilityModifiersCodeFixProvider.cs | 53 +++++++++++++------ .../Implementation/AbstractEditorFactory.cs | 16 ++++-- 2 files changed, 50 insertions(+), 19 deletions(-) diff --git a/src/Analyzers/Core/CodeFixes/AddAccessibilityModifiers/AbstractAddAccessibilityModifiersCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/AddAccessibilityModifiers/AbstractAddAccessibilityModifiersCodeFixProvider.cs index f3b9f136e8c32..3ed27071d9db1 100644 --- a/src/Analyzers/Core/CodeFixes/AddAccessibilityModifiers/AbstractAddAccessibilityModifiersCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/AddAccessibilityModifiers/AbstractAddAccessibilityModifiersCodeFixProvider.cs @@ -11,6 +11,7 @@ using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Editing; +using Microsoft.CodeAnalysis.LanguageServices; using Microsoft.CodeAnalysis.Shared.Extensions; using Roslyn.Utilities; @@ -43,28 +44,34 @@ public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) return Task.CompletedTask; } - protected sealed override async Task FixAllAsync( - Document document, ImmutableArray diagnostics, - SyntaxEditor editor, CancellationToken cancellationToken) + // Intended for use by AbstractEditorFactory to add accessibility when creating a new file. + internal static async Task GetTransformedSyntaxRootAsync(Document document, CancellationToken cancellationToken) { + var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); - - foreach (var diagnostic in diagnostics) + var syntaxFacts = document.GetRequiredLanguageService(); + var typeDeclarations = root.DescendantNodes().Where(node => syntaxFacts.IsTypeDeclaration(node)); + var editor = new SyntaxEditor(root, SyntaxGenerator.GetGenerator(document)); + foreach (var declaration in typeDeclarations) { - var declaration = diagnostic.AdditionalLocations[0].FindNode(cancellationToken); - var declarator = MapToDeclarator(declaration); + UpdateDeclaration(declaration, editor, semanticModel, cancellationToken); + } + + return editor.GetChangedRoot(); + } - var symbol = semanticModel.GetDeclaredSymbol(declarator, cancellationToken); - Contract.ThrowIfNull(symbol); + private static void UpdateDeclaration(SyntaxNode declaration, SyntaxEditor editor, SemanticModel semanticModel, CancellationToken cancellationToken) + { + var symbol = semanticModel.GetDeclaredSymbol(declaration, cancellationToken); + Contract.ThrowIfNull(symbol); - var preferredAccessibility = GetPreferredAccessibility(symbol); + var preferredAccessibility = GetPreferredAccessibility(symbol); - // Check to see if we need to add or remove - // If there's a modifier, then we need to remove it, otherwise no modifier, add it. - editor.ReplaceNode( - declaration, - (currentDeclaration, _) => UpdateAccessibility(currentDeclaration, preferredAccessibility)); - } + // Check to see if we need to add or remove + // If there's a modifier, then we need to remove it, otherwise no modifier, add it. + editor.ReplaceNode( + declaration, + (currentDeclaration, _) => UpdateAccessibility(currentDeclaration, preferredAccessibility)); return; @@ -80,6 +87,20 @@ SyntaxNode UpdateAccessibility(SyntaxNode declaration, Accessibility preferredAc } } + protected sealed override async Task FixAllAsync( + Document document, ImmutableArray diagnostics, + SyntaxEditor editor, CancellationToken cancellationToken) + { + var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); + + foreach (var diagnostic in diagnostics) + { + var declaration = diagnostic.AdditionalLocations[0].FindNode(cancellationToken); + var declarator = MapToDeclarator(declaration); + UpdateDeclaration(declarator, editor, semanticModel, cancellationToken); + } + } + private static Accessibility GetPreferredAccessibility(ISymbol symbol) { // If we have an overridden member, then if we're adding an accessibility modifier, use the diff --git a/src/VisualStudio/Core/Def/Implementation/AbstractEditorFactory.cs b/src/VisualStudio/Core/Def/Implementation/AbstractEditorFactory.cs index 79afe2a0db2a6..c4b0158da5872 100644 --- a/src/VisualStudio/Core/Def/Implementation/AbstractEditorFactory.cs +++ b/src/VisualStudio/Core/Def/Implementation/AbstractEditorFactory.cs @@ -9,6 +9,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.AddAccessibilityModifiers; using Microsoft.CodeAnalysis.CodeStyle; using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Editor.Host; @@ -331,11 +332,20 @@ private void FormatDocumentCreatedFromTemplate(IVsHierarchy hierarchy, uint item Contract.ThrowIfNull(rootToFormat); var documentOptions = ThreadHelper.JoinableTaskFactory.Run(() => addedDocument.GetOptionsAsync(cancellationToken)); + // Add access modifier + var rootWithAccessModifier = ThreadHelper.JoinableTaskFactory.Run(() => + { + return AbstractAddAccessibilityModifiersCodeFixProvider.GetTransformedSyntaxRootAsync(addedDocument, cancellationToken); + }); + + addedDocument = addedDocument.WithSyntaxRoot(rootWithAccessModifier); + rootToFormat = rootWithAccessModifier; + // Apply file header preferences var fileHeaderTemplate = documentOptions.GetOption(CodeStyleOptions2.FileHeaderTemplate); if (!string.IsNullOrEmpty(fileHeaderTemplate)) { - var documentWithFileHeader = ThreadHelper.JoinableTaskFactory.Run(() => + var rootWithFileHeader = ThreadHelper.JoinableTaskFactory.Run(() => { var newLineText = documentOptions.GetOption(FormattingOptions.NewLine, rootToFormat.Language); var newLineTrivia = SyntaxGeneratorInternal.EndOfLine(newLineText); @@ -347,8 +357,8 @@ private void FormatDocumentCreatedFromTemplate(IVsHierarchy hierarchy, uint item cancellationToken); }); - addedDocument = addedDocument.WithSyntaxRoot(documentWithFileHeader); - rootToFormat = documentWithFileHeader; + addedDocument = addedDocument.WithSyntaxRoot(rootWithFileHeader); + rootToFormat = rootWithFileHeader; } // Organize using directives From a358ab7e09565f99d5fb3c2521d782c1443df55b Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Wed, 17 Mar 2021 17:52:01 +0200 Subject: [PATCH 002/674] Update AbstractAddAccessibilityModifiersCodeFixProvider.cs --- .../AbstractAddAccessibilityModifiersCodeFixProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Analyzers/Core/CodeFixes/AddAccessibilityModifiers/AbstractAddAccessibilityModifiersCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/AddAccessibilityModifiers/AbstractAddAccessibilityModifiersCodeFixProvider.cs index 3ed27071d9db1..685794a4c188c 100644 --- a/src/Analyzers/Core/CodeFixes/AddAccessibilityModifiers/AbstractAddAccessibilityModifiersCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/AddAccessibilityModifiers/AbstractAddAccessibilityModifiersCodeFixProvider.cs @@ -51,7 +51,7 @@ internal static async Task GetTransformedSyntaxRootAsync(Document do var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); var syntaxFacts = document.GetRequiredLanguageService(); var typeDeclarations = root.DescendantNodes().Where(node => syntaxFacts.IsTypeDeclaration(node)); - var editor = new SyntaxEditor(root, SyntaxGenerator.GetGenerator(document)); + var editor = new SyntaxEditor(root, document.Project.Solution.Workspace); foreach (var declaration in typeDeclarations) { UpdateDeclaration(declaration, editor, semanticModel, cancellationToken); From 2e9a9073e0a093b573afe5170bc15521a2032b92 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Tue, 20 Apr 2021 13:55:51 -0700 Subject: [PATCH 003/674] Implement analysis scope solution explorer command --- src/VisualStudio/Core/Def/Commands.vsct | 69 ++++++++++ .../Core/Def/ID.RoslynCommands.cs | 8 +- .../VisualStudioDiagnosticAnalyzerService.cs | 122 +++++++++++++++++- .../Core/Def/PackageRegistration.pkgdef | 2 +- .../Core/Def/ServicesVSResources.resx | 12 ++ .../Core/Def/xlf/Commands.vsct.cs.xlf | 75 +++++++++++ .../Core/Def/xlf/Commands.vsct.de.xlf | 75 +++++++++++ .../Core/Def/xlf/Commands.vsct.es.xlf | 75 +++++++++++ .../Core/Def/xlf/Commands.vsct.fr.xlf | 75 +++++++++++ .../Core/Def/xlf/Commands.vsct.it.xlf | 75 +++++++++++ .../Core/Def/xlf/Commands.vsct.ja.xlf | 75 +++++++++++ .../Core/Def/xlf/Commands.vsct.ko.xlf | 75 +++++++++++ .../Core/Def/xlf/Commands.vsct.pl.xlf | 75 +++++++++++ .../Core/Def/xlf/Commands.vsct.pt-BR.xlf | 75 +++++++++++ .../Core/Def/xlf/Commands.vsct.ru.xlf | 75 +++++++++++ .../Core/Def/xlf/Commands.vsct.tr.xlf | 75 +++++++++++ .../Core/Def/xlf/Commands.vsct.zh-Hans.xlf | 75 +++++++++++ .../Core/Def/xlf/Commands.vsct.zh-Hant.xlf | 75 +++++++++++ .../Core/Def/xlf/ServicesVSResources.cs.xlf | 15 +++ .../Core/Def/xlf/ServicesVSResources.de.xlf | 15 +++ .../Core/Def/xlf/ServicesVSResources.es.xlf | 15 +++ .../Core/Def/xlf/ServicesVSResources.fr.xlf | 15 +++ .../Core/Def/xlf/ServicesVSResources.it.xlf | 15 +++ .../Core/Def/xlf/ServicesVSResources.ja.xlf | 15 +++ .../Core/Def/xlf/ServicesVSResources.ko.xlf | 15 +++ .../Core/Def/xlf/ServicesVSResources.pl.xlf | 15 +++ .../Def/xlf/ServicesVSResources.pt-BR.xlf | 15 +++ .../Core/Def/xlf/ServicesVSResources.ru.xlf | 15 +++ .../Core/Def/xlf/ServicesVSResources.tr.xlf | 15 +++ .../Def/xlf/ServicesVSResources.zh-Hans.xlf | 15 +++ .../Def/xlf/ServicesVSResources.zh-Hant.xlf | 15 +++ 31 files changed, 1377 insertions(+), 6 deletions(-) diff --git a/src/VisualStudio/Core/Def/Commands.vsct b/src/VisualStudio/Core/Def/Commands.vsct index 422b93c7d0bfd..c8ef47f4e2592 100644 --- a/src/VisualStudio/Core/Def/Commands.vsct +++ b/src/VisualStudio/Core/Def/Commands.vsct @@ -52,6 +52,10 @@ + + + + @@ -276,6 +280,48 @@ ErrorListSetSeverityNone + + + + +