From 2f3296e21b50090e2d445d5dfcac51483d23b4c8 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Sat, 3 Oct 2015 18:30:27 -0700 Subject: [PATCH] Enable Add Usings CodeFix in the Interactive window This is a prototype. If the approach seems acceptable, I'll add tests. --- .../Core/Portable/CodeFixes/CodeFixService.cs | 42 +++++++++++++++++-- ...activeDocumentSupportsSuggestionService.cs | 5 ++- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/Features/Core/Portable/CodeFixes/CodeFixService.cs b/src/Features/Core/Portable/CodeFixes/CodeFixService.cs index c478f080242..43f16d9a582 100644 --- a/src/Features/Core/Portable/CodeFixes/CodeFixService.cs +++ b/src/Features/Core/Portable/CodeFixes/CodeFixService.cs @@ -20,6 +20,7 @@ namespace Microsoft.CodeAnalysis.CodeFixes { using Microsoft.CodeAnalysis.ErrorLogger; + using System.Diagnostics; using DiagnosticId = String; using LanguageKind = String; @@ -146,7 +147,8 @@ public async Task> GetFixesAsync(Document documen result.Sort((d1, d2) => priorityMap.ContainsKey((CodeFixProvider)d1.Provider) ? (priorityMap.ContainsKey((CodeFixProvider)d2.Provider) ? priorityMap[(CodeFixProvider)d1.Provider] - priorityMap[(CodeFixProvider)d2.Provider] : -1) : 1); } - if (includeSuppressionFixes) + // TODO (https://github.com/dotnet/roslyn/issues/4932): Don't restrict CodeFixes in Interactive + if (document.Project.Solution.Workspace.Kind != WorkspaceKind.Interactive && includeSuppressionFixes) { foreach (var spanAndDiagnostic in aggregatedDiagnostics) { @@ -179,21 +181,38 @@ public async Task> GetFixesAsync(Document documen List projectFixers; var allFixers = new List(); + // TODO (https://github.com/dotnet/roslyn/issues/4932): Don't restrict CodeFixes in Interactive + bool isInteractive = document.Project.Solution.Workspace.Kind == WorkspaceKind.Interactive; + foreach (var diagnosticId in diagnosticDataCollection.Select(d => d.Id).Distinct()) { cancellationToken.ThrowIfCancellationRequested(); if (hasAnySharedFixer && fixerMap.Value.TryGetValue(diagnosticId, out workspaceFixers)) { - allFixers.AddRange(workspaceFixers); + if (isInteractive) + { + allFixers.AddRange(workspaceFixers.Where(IsInteractiveCodeFixProvider)); + } + else + { + allFixers.AddRange(workspaceFixers); + } } if (hasAnyProjectFixer && projectFixersMap.TryGetValue(diagnosticId, out projectFixers)) { + Debug.Assert(!isInteractive); allFixers.AddRange(projectFixers); } } + if (allFixers.Count == 0) + { + Debug.Assert(isInteractive); + return result; + } + var diagnostics = await DiagnosticData.ToDiagnosticsAsync(document.Project, diagnosticDataCollection, cancellationToken).ConfigureAwait(false); var extensionManager = document.Project.Solution.Workspace.Services.GetService(); @@ -350,6 +369,13 @@ private async Task ContainsAnyFix(Document document, DiagnosticData diagno bool hasAnySharedFixer = _workspaceFixersMap.TryGetValue(document.Project.Language, out fixerMap) && fixerMap.Value.TryGetValue(diagnostic.Id, out workspaceFixers); var hasAnyProjectFixer = GetProjectFixers(document.Project).TryGetValue(diagnostic.Id, out projectFixers); + // TODO (https://github.com/dotnet/roslyn/issues/4932): Don't restrict CodeFixes in Interactive + if (hasAnySharedFixer && document.Project.Solution.Workspace.Kind == WorkspaceKind.Interactive) + { + workspaceFixers = workspaceFixers.WhereAsArray(IsInteractiveCodeFixProvider); + hasAnySharedFixer = workspaceFixers.Any(); + } + Lazy lazySuppressionProvider = null; var hasSuppressionFixer = considerSuppressionFixes && @@ -411,6 +437,13 @@ private async Task ContainsAnyFix(Document document, DiagnosticData diagno return false; } + private bool IsInteractiveCodeFixProvider(CodeFixProvider provider) + { + // TODO (https://github.com/dotnet/roslyn/issues/4932): Don't restrict CodeFixes in Interactive + return provider is AddImport.AbstractAddImportCodeFixProvider || + provider is FullyQualify.AbstractFullyQualifyCodeFixProvider; + } + private static readonly Func> s_createList = _ => new List(); private ImmutableArray GetFixableDiagnosticIds(CodeFixProvider fixer, IExtensionManager extensionManager) @@ -537,7 +570,10 @@ private static ImmutableArray GetAndTestFixableDiagnosticIds(CodeFixProv private ImmutableDictionary> GetProjectFixers(Project project) { - return _projectFixersMap.GetValue(project.AnalyzerReferences, pId => ComputeProjectFixers(project)); + // TODO (https://github.com/dotnet/roslyn/issues/4932): Don't restrict CodeFixes in Interactive + return project.Solution.Workspace.Kind == WorkspaceKind.Interactive + ? ImmutableDictionary < DiagnosticId, List>.Empty + : _projectFixersMap.GetValue(project.AnalyzerReferences, pId => ComputeProjectFixers(project)); } private ImmutableDictionary> ComputeProjectFixers(Project project) diff --git a/src/Interactive/EditorFeatures/Core/Implementation/Interactive/InteractiveDocumentSupportsSuggestionService.cs b/src/Interactive/EditorFeatures/Core/Implementation/Interactive/InteractiveDocumentSupportsSuggestionService.cs index 764b45d1467..3508c0f60c4 100644 --- a/src/Interactive/EditorFeatures/Core/Implementation/Interactive/InteractiveDocumentSupportsSuggestionService.cs +++ b/src/Interactive/EditorFeatures/Core/Implementation/Interactive/InteractiveDocumentSupportsSuggestionService.cs @@ -11,7 +11,10 @@ internal sealed class InteractiveDocumentSupportsCodeFixService : IDocumentSuppo { public bool SupportsCodeFixes(Document document) { - return false; + // TODO (acasey): confirm with IDE team + var project = document.Project; + var projectIds = project.Solution.ProjectIds; + return project.DocumentIds[0] == document.Id && projectIds[projectIds.Count - 1] == project.Id; } public bool SupportsRefactorings(Document document) -- GitLab