提交 2f3296e2 编写于 作者: A Andrew Casey

Enable Add Usings CodeFix in the Interactive window

This is a prototype.  If the approach seems acceptable, I'll add tests.
上级 361117f1
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
namespace Microsoft.CodeAnalysis.CodeFixes namespace Microsoft.CodeAnalysis.CodeFixes
{ {
using Microsoft.CodeAnalysis.ErrorLogger; using Microsoft.CodeAnalysis.ErrorLogger;
using System.Diagnostics;
using DiagnosticId = String; using DiagnosticId = String;
using LanguageKind = String; using LanguageKind = String;
...@@ -146,7 +147,8 @@ public async Task<IEnumerable<CodeFixCollection>> GetFixesAsync(Document documen ...@@ -146,7 +147,8 @@ public async Task<IEnumerable<CodeFixCollection>> 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); 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) foreach (var spanAndDiagnostic in aggregatedDiagnostics)
{ {
...@@ -179,21 +181,38 @@ public async Task<IEnumerable<CodeFixCollection>> GetFixesAsync(Document documen ...@@ -179,21 +181,38 @@ public async Task<IEnumerable<CodeFixCollection>> GetFixesAsync(Document documen
List<CodeFixProvider> projectFixers; List<CodeFixProvider> projectFixers;
var allFixers = new List<CodeFixProvider>(); var allFixers = new List<CodeFixProvider>();
// 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()) foreach (var diagnosticId in diagnosticDataCollection.Select(d => d.Id).Distinct())
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
if (hasAnySharedFixer && fixerMap.Value.TryGetValue(diagnosticId, out workspaceFixers)) 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)) if (hasAnyProjectFixer && projectFixersMap.TryGetValue(diagnosticId, out projectFixers))
{ {
Debug.Assert(!isInteractive);
allFixers.AddRange(projectFixers); allFixers.AddRange(projectFixers);
} }
} }
if (allFixers.Count == 0)
{
Debug.Assert(isInteractive);
return result;
}
var diagnostics = await DiagnosticData.ToDiagnosticsAsync(document.Project, diagnosticDataCollection, cancellationToken).ConfigureAwait(false); var diagnostics = await DiagnosticData.ToDiagnosticsAsync(document.Project, diagnosticDataCollection, cancellationToken).ConfigureAwait(false);
var extensionManager = document.Project.Solution.Workspace.Services.GetService<IExtensionManager>(); var extensionManager = document.Project.Solution.Workspace.Services.GetService<IExtensionManager>();
...@@ -350,6 +369,13 @@ private async Task<bool> ContainsAnyFix(Document document, DiagnosticData diagno ...@@ -350,6 +369,13 @@ private async Task<bool> ContainsAnyFix(Document document, DiagnosticData diagno
bool hasAnySharedFixer = _workspaceFixersMap.TryGetValue(document.Project.Language, out fixerMap) && fixerMap.Value.TryGetValue(diagnostic.Id, out workspaceFixers); 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); 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<ISuppressionFixProvider> lazySuppressionProvider = null; Lazy<ISuppressionFixProvider> lazySuppressionProvider = null;
var hasSuppressionFixer = var hasSuppressionFixer =
considerSuppressionFixes && considerSuppressionFixes &&
...@@ -411,6 +437,13 @@ private async Task<bool> ContainsAnyFix(Document document, DiagnosticData diagno ...@@ -411,6 +437,13 @@ private async Task<bool> ContainsAnyFix(Document document, DiagnosticData diagno
return false; 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<DiagnosticId, List<CodeFixProvider>> s_createList = _ => new List<CodeFixProvider>(); private static readonly Func<DiagnosticId, List<CodeFixProvider>> s_createList = _ => new List<CodeFixProvider>();
private ImmutableArray<DiagnosticId> GetFixableDiagnosticIds(CodeFixProvider fixer, IExtensionManager extensionManager) private ImmutableArray<DiagnosticId> GetFixableDiagnosticIds(CodeFixProvider fixer, IExtensionManager extensionManager)
...@@ -537,7 +570,10 @@ private static ImmutableArray<string> GetAndTestFixableDiagnosticIds(CodeFixProv ...@@ -537,7 +570,10 @@ private static ImmutableArray<string> GetAndTestFixableDiagnosticIds(CodeFixProv
private ImmutableDictionary<DiagnosticId, List<CodeFixProvider>> GetProjectFixers(Project project) private ImmutableDictionary<DiagnosticId, List<CodeFixProvider>> 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<CodeFixProvider>>.Empty
: _projectFixersMap.GetValue(project.AnalyzerReferences, pId => ComputeProjectFixers(project));
} }
private ImmutableDictionary<DiagnosticId, List<CodeFixProvider>> ComputeProjectFixers(Project project) private ImmutableDictionary<DiagnosticId, List<CodeFixProvider>> ComputeProjectFixers(Project project)
......
...@@ -11,7 +11,10 @@ internal sealed class InteractiveDocumentSupportsCodeFixService : IDocumentSuppo ...@@ -11,7 +11,10 @@ internal sealed class InteractiveDocumentSupportsCodeFixService : IDocumentSuppo
{ {
public bool SupportsCodeFixes(Document document) 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) public bool SupportsRefactorings(Document document)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册