提交 0fbb07fe 编写于 作者: D David Barbet

Move repeated workspace methods to extension and cleanup command handlers.

上级 9ea88834
......@@ -24,19 +24,9 @@ public VSCommanding.CommandState GetCommandState(RenameCommandArgs args)
return VSCommanding.CommandState.Unspecified;
}
var textContainer = args.SubjectBuffer.AsTextContainer();
if (!Workspace.TryGetWorkspace(textContainer, out var workspace))
{
return VSCommanding.CommandState.Unspecified;
}
if (!workspace.CanApplyChange(ApplyChangesKind.ChangeDocument))
{
return VSCommanding.CommandState.Unspecified;
}
var supportsFeatureService = workspace.Services.GetService<ITextBufferSupportsFeatureService>();
if (!supportsFeatureService.SupportsRename(args.SubjectBuffer))
if (!args.SubjectBuffer.TryGetOwningWorkspace(out var workspace) ||
!workspace.CanApplyChange(ApplyChangesKind.ChangeDocument) ||
!args.SubjectBuffer.SupportsRename(workspace))
{
return VSCommanding.CommandState.Unspecified;
}
......@@ -56,8 +46,7 @@ public bool ExecuteCommand(RenameCommandArgs args, CommandExecutionContext conte
private void ExecuteRenameWorker(RenameCommandArgs args, CommandExecutionContext context)
{
var snapshot = args.SubjectBuffer.CurrentSnapshot;
if (!Workspace.TryGetWorkspace(snapshot.AsText().Container, out var workspace))
if (!args.SubjectBuffer.TryGetOwningWorkspace(out var workspace))
{
return;
}
......@@ -87,7 +76,6 @@ private void ExecuteRenameWorker(RenameCommandArgs args, CommandExecutionContext
}
}
var position = caretPoint.Value;
var cancellationToken = context.OperationContext.UserCancellationToken;
var document = args.SubjectBuffer.CurrentSnapshot.GetFullyLoadedOpenDocumentInCurrentContextWithChangesAsync(
context.OperationContext).WaitAndGetResult(cancellationToken);
......
......@@ -53,13 +53,12 @@ internal class OpenTextBufferManager : ForegroundThreadAffinitizedObject
InlineRenameSession session,
ITextBuffer subjectBuffer,
Workspace workspace,
IEnumerable<Document> documents,
ITextBufferFactoryService textBufferFactoryService)
: base(session.ThreadingContext)
{
_session = session;
_subjectBuffer = subjectBuffer;
_baseDocuments = documents;
_baseDocuments = subjectBuffer.GetRelatedDocuments();
_textBufferFactoryService = textBufferFactoryService;
_subjectBuffer.ChangedLowPriority += OnTextBufferChanged;
......
......@@ -208,7 +208,7 @@ private void InitializeOpenBuffers(SnapshotSpan triggerSpan)
foreach (var buffer in openBuffers)
{
TryPopulateOpenTextBufferManagerForBuffer(buffer, buffer.AsTextContainer().GetRelatedDocuments());
TryPopulateOpenTextBufferManagerForBuffer(buffer);
}
}
......@@ -230,14 +230,14 @@ private void InitializeOpenBuffers(SnapshotSpan triggerSpan)
RenameTrackingDismisser.DismissRenameTracking(_workspace, _workspace.GetOpenDocumentIds());
}
private bool TryPopulateOpenTextBufferManagerForBuffer(ITextBuffer buffer, IEnumerable<Document> documents)
private bool TryPopulateOpenTextBufferManagerForBuffer(ITextBuffer buffer)
{
AssertIsForeground();
VerifyNotDismissed();
if (_workspace.Kind == WorkspaceKind.Interactive)
{
Debug.Assert(documents.Count() == 1); // No linked files.
Debug.Assert(buffer.GetRelatedDocuments().Count() == 1);
Debug.Assert(buffer.IsReadOnly(0) == buffer.IsReadOnly(Span.FromBounds(0, buffer.CurrentSnapshot.Length))); // All or nothing.
if (buffer.IsReadOnly(0))
{
......@@ -245,11 +245,9 @@ private bool TryPopulateOpenTextBufferManagerForBuffer(ITextBuffer buffer, IEnum
}
}
var documentSupportsFeatureService = _workspace.Services.GetService<ITextBufferSupportsFeatureService>();
if (!_openTextBuffers.ContainsKey(buffer) && documentSupportsFeatureService.SupportsRename(buffer))
if (!_openTextBuffers.ContainsKey(buffer) && buffer.SupportsRename(_workspace))
{
_openTextBuffers[buffer] = new OpenTextBufferManager(this, buffer, _workspace, documents, _textBufferFactoryService);
_openTextBuffers[buffer] = new OpenTextBufferManager(this, buffer, _workspace, _textBufferFactoryService);
return true;
}
......@@ -263,8 +261,7 @@ private void OnSubjectBuffersConnected(object sender, SubjectBuffersConnectedEve
{
if (buffer.GetWorkspace() == _workspace)
{
var documents = buffer.AsTextContainer().GetRelatedDocuments();
if (TryPopulateOpenTextBufferManagerForBuffer(buffer, documents))
if (TryPopulateOpenTextBufferManagerForBuffer(buffer))
{
_openTextBuffers[buffer].ConnectToView(e.TextView);
}
......
......@@ -326,7 +326,7 @@ private SuggestedActionSet InlineActions(SuggestedActionSet actionSet)
this.AssertIsForeground();
if (_owner._codeFixService != null &&
supportsFeatureService.SupportsCodeFixes(_subjectBuffer) &&
_subjectBuffer.SupportsCodeFixes(workspace) &&
requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.CodeFix))
{
// We only include suppressions if light bulb is asking for everything.
......@@ -641,7 +641,7 @@ private static SuggestedActionSetPriority GetSuggestedActionSetPriority(CodeActi
if (workspace.Options.GetOption(EditorComponentOnOffOptions.CodeRefactorings) &&
_owner._codeRefactoringService != null &&
supportsFeatureService.SupportsRefactorings(_subjectBuffer) &&
_subjectBuffer.SupportsRefactorings(workspace) &&
requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.Refactoring))
{
// It may seem strange that we kick off a task, but then immediately 'Wait' on
......@@ -791,10 +791,9 @@ private static SuggestedActionSetPriority GetSuggestedActionSetPriority(CodeActi
CancellationToken cancellationToken)
{
var workspace = document.Project.Solution.Workspace;
var supportsFeatureService = workspace.Services.GetService<ITextBufferSupportsFeatureService>();
if (provider._codeFixService != null &&
supportsFeatureService.SupportsCodeFixes(_subjectBuffer))
_subjectBuffer.SupportsCodeFixes(workspace))
{
var result = await provider._codeFixService.GetMostSevereFixableDiagnosticAsync(
document, range.Span.ToTextSpan(), cancellationToken).ConfigureAwait(false);
......@@ -830,11 +829,10 @@ private static SuggestedActionSetPriority GetSuggestedActionSetPriority(CodeActi
}
var workspace = document.Project.Solution.Workspace;
var supportsFeatureService = workspace.Services.GetService<ITextBufferSupportsFeatureService>();
if (document.Project.Solution.Options.GetOption(EditorComponentOnOffOptions.CodeRefactorings) &&
provider._codeRefactoringService != null &&
supportsFeatureService.SupportsRefactorings(_subjectBuffer))
_subjectBuffer.SupportsRefactorings(workspace))
{
if (await provider._codeRefactoringService.HasRefactoringsAsync(
document, selection.Value, cancellationToken).ConfigureAwait(false))
......
......@@ -60,32 +60,48 @@ public bool ExecuteCommand(GoToPreviousMemberCommandArgs args, CommandExecutionC
private VSCommanding.CommandState GetCommandStateImpl(EditorCommandArgs args)
{
var document = args.SubjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
var caretPoint = args.TextView.GetCaretPoint(args.SubjectBuffer);
return IsAvailable(document, caretPoint, args.SubjectBuffer) ? VSCommanding.CommandState.Available : VSCommanding.CommandState.Unspecified;
if (!IsAvailable(caretPoint, args.SubjectBuffer))
{
return VSCommanding.CommandState.Unspecified;
}
var document = args.SubjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
if (document?.SupportsSyntaxTree != true)
{
return VSCommanding.CommandState.Unspecified;
}
return VSCommanding.CommandState.Available;
}
private static bool IsAvailable(Document document, SnapshotPoint? caretPoint, ITextBuffer subjectBuffer)
private static bool IsAvailable(SnapshotPoint? caretPoint, ITextBuffer subjectBuffer)
{
if (document?.SupportsSyntaxTree != true)
if (!caretPoint.HasValue)
{
return false;
}
if (!caretPoint.HasValue)
if (!subjectBuffer.TryGetOwningWorkspace(out var workspace) ||
!subjectBuffer.SupportsNavigationToAnyPosition(workspace))
{
return false;
}
var documentSupportsFeatureService = document.Project.Solution.Workspace.Services.GetService<ITextBufferSupportsFeatureService>();
return documentSupportsFeatureService?.SupportsNavigationToAnyPosition(subjectBuffer) == true;
return true;
}
private bool ExecuteCommandImpl(EditorCommandArgs args, bool gotoNextMember, CommandExecutionContext context)
{
var document = args.SubjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
var caretPoint = args.TextView.GetCaretPoint(args.SubjectBuffer);
if (!IsAvailable(document, caretPoint, args.SubjectBuffer))
if (!IsAvailable(caretPoint, args.SubjectBuffer))
{
return false;
}
var document = args.SubjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
if (document?.SupportsSyntaxTree != true)
{
return false;
}
......
......@@ -52,7 +52,7 @@ public bool ExecuteCommand(GoToImplementationCommandArgs args, CommandExecutionC
using (context.OperationContext.AddScope(allowCancellation: true, EditorFeaturesResources.Locating_implementations))
{
var subjectBuffer = args.SubjectBuffer;
if (!Workspace.TryGetWorkspace(subjectBuffer.AsTextContainer(), out var workspace))
if (!subjectBuffer.TryGetOwningWorkspace(out var workspace))
{
return false;
}
......
......@@ -30,20 +30,7 @@ public VSCommanding.CommandState GetCommandState(RemoveParametersCommandArgs arg
private static VSCommanding.CommandState GetCommandState(ITextBuffer subjectBuffer)
{
var document = subjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
if (document == null ||
!document.Project.Solution.Workspace.CanApplyChange(ApplyChangesKind.ChangeDocument))
{
return VSCommanding.CommandState.Unspecified;
}
var supportsFeatureService = document.Project.Solution.Workspace.Services.GetService<ITextBufferSupportsFeatureService>();
if (!supportsFeatureService.SupportsRefactorings(subjectBuffer))
{
return VSCommanding.CommandState.Unspecified;
}
return VSCommanding.CommandState.Available;
return IsAvailable(subjectBuffer) ? VSCommanding.CommandState.Available : VSCommanding.CommandState.Unspecified;
}
public bool ExecuteCommand(RemoveParametersCommandArgs args, CommandExecutionContext context)
......@@ -52,22 +39,23 @@ public bool ExecuteCommand(RemoveParametersCommandArgs args, CommandExecutionCon
public bool ExecuteCommand(ReorderParametersCommandArgs args, CommandExecutionContext context)
=> ExecuteCommand(args.TextView, args.SubjectBuffer, context);
private bool ExecuteCommand(ITextView textView, ITextBuffer subjectBuffer, CommandExecutionContext context)
private static bool IsAvailable(ITextBuffer subjectBuffer)
{
using (context.OperationContext.AddScope(allowCancellation: true, FeaturesResources.Change_signature))
if (!subjectBuffer.TryGetOwningWorkspace(out var workspace) ||
!workspace.CanApplyChange(ApplyChangesKind.ChangeDocument) ||
!subjectBuffer.SupportsRefactorings(workspace))
{
if (!Workspace.TryGetWorkspace(subjectBuffer.AsTextContainer(), out var workspace))
{
return false;
}
return false;
}
if (!workspace.CanApplyChange(ApplyChangesKind.ChangeDocument))
{
return false;
}
return true;
}
var supportsFeatureService = workspace.Services.GetService<ITextBufferSupportsFeatureService>();
if (!supportsFeatureService.SupportsRefactorings(subjectBuffer))
private bool ExecuteCommand(ITextView textView, ITextBuffer subjectBuffer, CommandExecutionContext context)
{
using (context.OperationContext.AddScope(allowCancellation: true, FeaturesResources.Change_signature))
{
if (IsAvailable(subjectBuffer))
{
return false;
}
......
......@@ -37,15 +37,7 @@ internal abstract class AbstractEncapsulateFieldCommandHandler : VSCommanding.IC
public bool ExecuteCommand(EncapsulateFieldCommandArgs args, CommandExecutionContext context)
{
var document = args.SubjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
if (document == null)
{
return false;
}
var workspace = document.Project.Solution.Workspace;
var supportsFeatureService = workspace.Services.GetService<ITextBufferSupportsFeatureService>();
if (!supportsFeatureService.SupportsRefactorings(args.SubjectBuffer))
if (!args.SubjectBuffer.SupportsRefactorings())
{
return false;
}
......@@ -127,19 +119,7 @@ private bool Execute(EncapsulateFieldCommandArgs args, IUIThreadOperationScope w
public VSCommanding.CommandState GetCommandState(EncapsulateFieldCommandArgs args)
{
var document = args.SubjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
if (document == null)
{
return VSCommanding.CommandState.Unspecified;
}
var supportsFeatureService = document.Project.Solution.Workspace.Services.GetService<ITextBufferSupportsFeatureService>();
if (!supportsFeatureService.SupportsRefactorings(args.SubjectBuffer))
{
return VSCommanding.CommandState.Unspecified;
}
return VSCommanding.CommandState.Available;
return args.SubjectBuffer.SupportsRefactorings() ? VSCommanding.CommandState.Available : VSCommanding.CommandState.Unspecified;
}
}
}
......@@ -10,6 +10,7 @@
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.Commanding;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor.Commanding.Commands;
using Roslyn.Utilities;
using VSCommanding = Microsoft.VisualStudio.Commanding;
......@@ -29,21 +30,7 @@ protected AbstractExtractInterfaceCommandHandler(IThreadingContext threadingCont
public VSCommanding.CommandState GetCommandState(ExtractInterfaceCommandArgs args)
{
var document = args.SubjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
if (document == null ||
!document.Project.Solution.Workspace.CanApplyChange(ApplyChangesKind.AddDocument) ||
!document.Project.Solution.Workspace.CanApplyChange(ApplyChangesKind.ChangeDocument))
{
return VSCommanding.CommandState.Unspecified;
}
var supportsFeatureService = document.Project.Solution.Workspace.Services.GetService<ITextBufferSupportsFeatureService>();
if (!supportsFeatureService.SupportsRefactorings(args.SubjectBuffer))
{
return VSCommanding.CommandState.Unspecified;
}
return VSCommanding.CommandState.Available;
return IsAvailable(args.SubjectBuffer, out var _) ? VSCommanding.CommandState.Available : VSCommanding.CommandState.Unspecified;
}
public bool ExecuteCommand(ExtractInterfaceCommandArgs args, CommandExecutionContext context)
......@@ -51,19 +38,7 @@ public bool ExecuteCommand(ExtractInterfaceCommandArgs args, CommandExecutionCon
using (context.OperationContext.AddScope(allowCancellation: true, EditorFeaturesResources.Extract_Interface))
{
var subjectBuffer = args.SubjectBuffer;
if (!Workspace.TryGetWorkspace(subjectBuffer.AsTextContainer(), out var workspace))
{
return false;
}
if (!workspace.CanApplyChange(ApplyChangesKind.AddDocument) ||
!workspace.CanApplyChange(ApplyChangesKind.ChangeDocument))
{
return false;
}
var supportsFeatureService = workspace.Services.GetService<ITextBufferSupportsFeatureService>();
if (!supportsFeatureService.SupportsRefactorings(subjectBuffer))
if (!IsAvailable(subjectBuffer, out var workspace))
{
return false;
}
......@@ -110,5 +85,20 @@ public bool ExecuteCommand(ExtractInterfaceCommandArgs args, CommandExecutionCon
return true;
}
}
private static bool IsAvailable(ITextBuffer subjectBuffer, out Workspace workspace)
{
if (!subjectBuffer.TryGetOwningWorkspace(out var retrievedWorkspace) ||
!retrievedWorkspace.CanApplyChange(ApplyChangesKind.AddDocument) ||
!retrievedWorkspace.CanApplyChange(ApplyChangesKind.ChangeDocument) ||
!subjectBuffer.SupportsRefactorings(retrievedWorkspace))
{
workspace = retrievedWorkspace;
return false;
}
workspace = retrievedWorkspace;
return true;
}
}
}
......@@ -50,19 +50,9 @@ public VSCommanding.CommandState GetCommandState(ExtractMethodCommandArgs args)
return VSCommanding.CommandState.Unspecified;
}
var document = args.SubjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
if (document == null)
{
return VSCommanding.CommandState.Unspecified;
}
if (!document.Project.Solution.Workspace.CanApplyChange(ApplyChangesKind.ChangeDocument))
{
return VSCommanding.CommandState.Unspecified;
}
var supportsFeatureService = document.Project.Solution.Workspace.Services.GetService<ITextBufferSupportsFeatureService>();
if (!supportsFeatureService.SupportsRefactorings(args.SubjectBuffer))
if (!args.SubjectBuffer.TryGetOwningWorkspace(out var workspace) ||
!workspace.CanApplyChange(ApplyChangesKind.ChangeDocument) ||
!args.SubjectBuffer.SupportsRefactorings(workspace))
{
return VSCommanding.CommandState.Unspecified;
}
......@@ -79,20 +69,7 @@ public bool ExecuteCommand(ExtractMethodCommandArgs args, CommandExecutionContex
_renameService.ActiveSession.Commit();
}
var subjectBuffer = args.SubjectBuffer;
if (!Workspace.TryGetWorkspace(subjectBuffer.AsTextContainer(), out var workspace))
{
return false;
}
var supportsFeatureService = workspace.Services.GetService<ITextBufferSupportsFeatureService>();
if (!supportsFeatureService.SupportsRefactorings(subjectBuffer))
{
return false;
}
var document = subjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
if (document == null)
if (!args.SubjectBuffer.SupportsRefactorings())
{
return false;
}
......
......@@ -77,26 +77,23 @@ private VSCommanding.CommandState GetCommandState(EditorCommandArgs args, Func<I
private bool IsCommandSupported(EditorCommandArgs args, out Workspace workspace)
{
workspace = null;
var document = args.SubjectBuffer.AsTextContainer().GetOpenDocumentInCurrentContext();
if (document == null)
if (args.SubjectBuffer.TryGetOwningWorkspace(out var retrievedWorkspace))
{
return false;
}
workspace = document.Project.Solution.Workspace;
workspace = retrievedWorkspace;
if (!workspace.CanApplyChange(ApplyChangesKind.ChangeDocument))
{
return false;
}
if (!workspace.CanApplyChange(ApplyChangesKind.ChangeDocument))
{
return false;
}
if (workspace.Kind == WorkspaceKind.MiscellaneousFiles)
{
return false;
}
if (workspace.Kind == WorkspaceKind.MiscellaneousFiles)
{
return false;
return args.SubjectBuffer.SupportsRefactorings(workspace);
}
return workspace.Services.GetService<ITextBufferSupportsFeatureService>().SupportsRefactorings(args.SubjectBuffer);
return false;
}
public bool ExecuteCommand(SortAndRemoveUnnecessaryImportsCommandArgs args, CommandExecutionContext context)
......
......@@ -43,5 +43,63 @@ internal static bool GetFeatureOnOffOption(this ITextBuffer buffer, PerLanguageO
throw ExceptionUtilities.Unreachable;
}
}
internal static bool TryGetOwningWorkspace(this ITextBuffer buffer, out Workspace workspace)
{
workspace = null;
if (Workspace.TryGetWorkspace(buffer.AsTextContainer(), out var retrievedWorkspace))
{
workspace = retrievedWorkspace;
}
return workspace != null;
}
/// <summary>
/// Checks if the buffer supports refactorings.
/// Additionally retrieves the workspace for the buffer.
/// </summary>
internal static bool SupportsRefactorings(this ITextBuffer buffer)
{
return buffer.TryGetOwningWorkspace(out var workspace) && buffer.SupportsRefactorings(workspace);
}
/// <summary>
/// Checks if a buffer supports refactorings.
/// </summary>
internal static bool SupportsRefactorings(this ITextBuffer buffer, Workspace workspace)
{
return TryGetSupportsFeatureService(workspace, out var service) && service.SupportsRefactorings(buffer);
}
/// <summary>
/// Checks if a buffer supports rename.
/// </summary>
internal static bool SupportsRename(this ITextBuffer buffer, Workspace workspace)
{
return TryGetSupportsFeatureService(workspace, out var service) && service.SupportsRename(buffer);
}
/// <summary>
/// Checks if a buffer supports code fixes.
/// </summary>
internal static bool SupportsCodeFixes(this ITextBuffer buffer, Workspace workspace)
{
return TryGetSupportsFeatureService(workspace, out var service) && service.SupportsCodeFixes(buffer);
}
/// <summary>
/// Checks if a buffer supports navigation.
/// </summary>
internal static bool SupportsNavigationToAnyPosition(this ITextBuffer buffer, Workspace workspace)
{
return TryGetSupportsFeatureService(workspace, out var service) && service.SupportsNavigationToAnyPosition(buffer);
}
private static bool TryGetSupportsFeatureService(Workspace workspace, out ITextBufferSupportsFeatureService service)
{
service = workspace.Services.GetService<ITextBufferSupportsFeatureService>();
return service != null;
}
}
}
......@@ -27,7 +27,7 @@ public bool SupportsRefactorings(ITextBuffer textBuffer)
public bool SupportsRename(ITextBuffer textBuffer)
{
var sourceTextContainer = textBuffer.CurrentSnapshot.AsText().Container;
var sourceTextContainer = textBuffer.AsTextContainer();
if (Workspace.TryGetWorkspace(sourceTextContainer, out var workspace))
{
return workspace.GetRelatedDocumentIds(sourceTextContainer)
......@@ -45,7 +45,7 @@ public bool SupportsNavigationToAnyPosition(ITextBuffer textBuffer)
private static ContainedDocument GetContainedDocument(ITextBuffer textBuffer)
{
var sourceTextContainer = textBuffer.CurrentSnapshot.AsText().Container;
var sourceTextContainer = textBuffer.AsTextContainer();
if (Workspace.TryGetWorkspace(sourceTextContainer, out var workspace)
&& workspace is VisualStudioWorkspaceImpl vsWorkspace)
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册