public EventHookupSession( EventHookupSessionManager eventHookupSessionManager, EventHookupCommandHandler commandHandler, ITextView textView, ITextBuffer subjectBuffer, IAsynchronousOperationListener asyncListener, Mutex testSessionHookupMutex) : base(eventHookupSessionManager.ThreadingContext) { AssertIsForeground(); _cancellationTokenSource = new CancellationTokenSource(); var cancellationToken = _cancellationTokenSource.Token; _textView = textView; _subjectBuffer = subjectBuffer; this.TESTSessionHookupMutex = testSessionHookupMutex; var document = textView.TextSnapshot.GetOpenDocumentInCurrentContextWithChanges(); if (document != null && document.Project.Solution.Workspace.CanApplyChange(ApplyChangesKind.ChangeDocument)) { var position = textView.GetCaretPoint(subjectBuffer).Value.Position; _trackingPoint = textView.TextSnapshot.CreateTrackingPoint(position, PointTrackingMode.Negative); // If the caret is at the end of the document we just create an empty span var length = textView.TextSnapshot.Length > position + 1 ? 1 : 0; _trackingSpan = textView.TextSnapshot.CreateTrackingSpan(new Span(position, length), SpanTrackingMode.EdgeInclusive); var asyncToken = asyncListener.BeginAsyncOperation(GetType().Name + ".Start"); this.GetEventNameTask = Task.Factory.SafeStartNewFromAsync( () => DetermineIfEventHookupAndGetHandlerNameAsync(document, position, cancellationToken), cancellationToken, TaskScheduler.Default); var continuedTask = this.GetEventNameTask.SafeContinueWithFromAsync( async t => { await ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(alwaysYield: true, cancellationToken); if (t.Result != null) { commandHandler.EventHookupSessionManager.EventHookupFoundInSession(this); } }, cancellationToken, TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default); continuedTask.CompletesAsyncOperation(asyncToken); } else { _trackingPoint = textView.TextSnapshot.CreateTrackingPoint(0, PointTrackingMode.Negative); _trackingSpan = textView.TextSnapshot.CreateTrackingSpan(new Span(), SpanTrackingMode.EdgeInclusive); this.GetEventNameTask = SpecializedTasks.Null <string>(); eventHookupSessionManager.CancelAndDismissExistingSessions(); } }
private void HandleTabWorker( ITextView textView, ITextBuffer subjectBuffer, Action nextHandler, CancellationToken cancellationToken ) { AssertIsForeground(); // For test purposes only! if (EventHookupSessionManager.CurrentSession.TESTSessionHookupMutex != null) { try { EventHookupSessionManager.CurrentSession.TESTSessionHookupMutex.ReleaseMutex(); } catch (ApplicationException) { } } // Blocking wait (if necessary) to determine whether to consume the tab and // generate the event handler. EventHookupSessionManager.CurrentSession.GetEventNameTask.Wait(cancellationToken); string eventHandlerMethodName = null; if ( EventHookupSessionManager.CurrentSession.GetEventNameTask.Status == TaskStatus.RanToCompletion ) { eventHandlerMethodName = EventHookupSessionManager.CurrentSession.GetEventNameTask.WaitAndGetResult( cancellationToken ); } if ( eventHandlerMethodName == null || EventHookupSessionManager.CurrentSession.TextView != textView ) { nextHandler(); EventHookupSessionManager.CancelAndDismissExistingSessions(); return; } // This tab means we should generate the event handler method. Begin the code // generation process. GenerateAndAddEventHandler( textView, subjectBuffer, eventHandlerMethodName, nextHandler, cancellationToken ); }
public EventHookupCommandHandler( IInlineRenameService inlineRenameService, IAsynchronousOperationListenerProvider listenerProvider, EventHookupSessionManager eventHookupSessionManager) { _inlineRenameService = inlineRenameService; _asyncListener = listenerProvider.GetListener(FeatureAttribute.EventHookup); this.EventHookupSessionManager = eventHookupSessionManager; }
private void GenerateAndAddEventHandler( ITextView textView, ITextBuffer subjectBuffer, string eventHandlerMethodName, Action nextHandler, CancellationToken cancellationToken ) { AssertIsForeground(); using (Logger.LogBlock(FunctionId.EventHookup_Generate_Handler, cancellationToken)) { EventHookupSessionManager.CancelAndDismissExistingSessions(); var workspace = textView.TextSnapshot.TextBuffer.GetWorkspace(); if (workspace == null) { nextHandler(); EventHookupSessionManager.CancelAndDismissExistingSessions(); return; } var document = textView.TextSnapshot.GetOpenDocumentInCurrentContextWithChanges(); Contract.ThrowIfNull( document, "Event Hookup could not find the document for the IBufferView." ); var position = textView.GetCaretPoint(subjectBuffer).Value.Position; var solutionWithEventHandler = CreateSolutionWithEventHandler( document, eventHandlerMethodName, position, out var plusEqualTokenEndPosition, cancellationToken ); Contract.ThrowIfNull( solutionWithEventHandler, "Event Hookup could not create solution with event handler." ); // The new solution is created, so start user observable changes Contract.ThrowIfFalse( workspace.TryApplyChanges(solutionWithEventHandler), "Event Hookup could not update the solution." ); // The += token will not move during this process, so it is safe to use that // position as a location from which to find the identifier we're renaming. BeginInlineRename(textView, plusEqualTokenEndPosition, cancellationToken); } }
public EventHookupSession( EventHookupSessionManager eventHookupSessionManager, EventHookupCommandHandler commandHandler, ITextView textView, ITextBuffer subjectBuffer, IAsynchronousOperationListener asyncListener, Mutex testSessionHookupMutex) { AssertIsForeground(); _cancellationTokenSource = new CancellationTokenSource(); _textView = textView; _subjectBuffer = subjectBuffer; this.TESTSessionHookupMutex = testSessionHookupMutex; var document = textView.TextSnapshot.GetOpenDocumentInCurrentContextWithChanges(); if (document != null && document.Project.Solution.Workspace.CanApplyChange(ApplyChangesKind.ChangeDocument)) { var position = textView.GetCaretPoint(subjectBuffer).Value.Position; _trackingPoint = textView.TextSnapshot.CreateTrackingPoint(position, PointTrackingMode.Negative); _trackingSpan = textView.TextSnapshot.CreateTrackingSpan(new Span(position, 1), SpanTrackingMode.EdgeInclusive); var asyncToken = asyncListener.BeginAsyncOperation(GetType().Name + ".Start"); this.GetEventNameTask = Task.Factory.SafeStartNewFromAsync( () => DetermineIfEventHookupAndGetHandlerNameAsync(document, position, _cancellationTokenSource.Token), _cancellationTokenSource.Token, TaskScheduler.Default); var continuedTask = this.GetEventNameTask.SafeContinueWith(t => { AssertIsForeground(); if (t.Result != null) { commandHandler.EventHookupSessionManager.EventHookupFoundInSession(this); } }, _cancellationTokenSource.Token, TaskContinuationOptions.OnlyOnRanToCompletion, ForegroundThreadAffinitizedObject.DefaultForegroundThreadData.TaskScheduler); continuedTask.CompletesAsyncOperation(asyncToken); } else { _trackingPoint = textView.TextSnapshot.CreateTrackingPoint(0, PointTrackingMode.Negative); _trackingSpan = textView.TextSnapshot.CreateTrackingSpan(new Span(), SpanTrackingMode.EdgeInclusive); this.GetEventNameTask = SpecializedTasks.Default <string>(); eventHookupSessionManager.CancelAndDismissExistingSessions(); } }
public EventHookupCommandHandler( IInlineRenameService inlineRenameService, #pragma warning disable CS0618 // IQuickInfo* is obsolete, tracked by https://github.com/dotnet/roslyn/issues/24094 IQuickInfoBroker quickInfoBroker, #pragma warning restore CS0618 // IQuickInfo* is obsolete, tracked by https://github.com/dotnet/roslyn/issues/24094 [Import(AllowDefault = true)] IHACK_EventHookupDismissalOnBufferChangePreventerService prematureDismissalPreventer, IAsynchronousOperationListenerProvider listenerProvider) { _inlineRenameService = inlineRenameService; _prematureDismissalPreventer = prematureDismissalPreventer; _asyncListener = listenerProvider.GetListener(FeatureAttribute.EventHookup); this.EventHookupSessionManager = new EventHookupSessionManager(prematureDismissalPreventer, quickInfoBroker); }
public EventHookupCommandHandler( IInlineRenameService inlineRenameService, Microsoft.CodeAnalysis.Editor.Host.IWaitIndicator waitIndicator, IQuickInfoBroker quickInfoBroker, [Import(AllowDefault = true)] IHACK_EventHookupDismissalOnBufferChangePreventerService prematureDismissalPreventer, [ImportMany] IEnumerable<Lazy<IAsynchronousOperationListener, FeatureMetadata>> asyncListeners) { _inlineRenameService = inlineRenameService; _waitIndicator = waitIndicator; _prematureDismissalPreventer = prematureDismissalPreventer; _asyncListener = new AggregateAsynchronousOperationListener(asyncListeners, FeatureAttribute.EventHookup); this.EventHookupSessionManager = new EventHookupSessionManager(prematureDismissalPreventer, quickInfoBroker); }
public EventHookupCommandHandler( IThreadingContext threadingContext, IInlineRenameService inlineRenameService, EventHookupSessionManager eventHookupSessionManager, IGlobalOptionService globalOptions, IAsynchronousOperationListenerProvider listenerProvider) { _threadingContext = threadingContext; _inlineRenameService = inlineRenameService; _asyncListener = listenerProvider.GetListener(FeatureAttribute.EventHookup); _globalOptions = globalOptions; this.EventHookupSessionManager = eventHookupSessionManager; }
public EventHookupCommandHandler( IInlineRenameService inlineRenameService, Microsoft.CodeAnalysis.Editor.Host.IWaitIndicator waitIndicator, IQuickInfoBroker quickInfoBroker, [Import(AllowDefault = true)] IHACK_EventHookupDismissalOnBufferChangePreventerService prematureDismissalPreventer, [ImportMany] IEnumerable <Lazy <IAsynchronousOperationListener, FeatureMetadata> > asyncListeners) { _inlineRenameService = inlineRenameService; _waitIndicator = waitIndicator; _prematureDismissalPreventer = prematureDismissalPreventer; _asyncListener = new AggregateAsynchronousOperationListener(asyncListeners, FeatureAttribute.EventHookup); this.EventHookupSessionManager = new EventHookupSessionManager(prematureDismissalPreventer, quickInfoBroker); }
public EventHookupCommandHandler( IInlineRenameService inlineRenameService, Microsoft.CodeAnalysis.Editor.Host.IWaitIndicator waitIndicator, IQuickInfoBroker quickInfoBroker, [Import(AllowDefault = true)] IHACK_EventHookupDismissalOnBufferChangePreventerService prematureDismissalPreventer, IAsynchronousOperationListenerProvider listenerProvider) { _inlineRenameService = inlineRenameService; _waitIndicator = waitIndicator; _prematureDismissalPreventer = prematureDismissalPreventer; _asyncListener = listenerProvider.GetListener(FeatureAttribute.EventHookup); this.EventHookupSessionManager = new EventHookupSessionManager(prematureDismissalPreventer, quickInfoBroker); }
public void ExecuteCommand( TypeCharCommandArgs args, Action nextHandler, CommandExecutionContext context ) { AssertIsForeground(); nextHandler(); if (!args.SubjectBuffer.GetFeatureOnOffOption(InternalFeatureOnOffOptions.EventHookup)) { EventHookupSessionManager.CancelAndDismissExistingSessions(); return; } // Event hookup is current uncancellable. var cancellationToken = CancellationToken.None; using (Logger.LogBlock(FunctionId.EventHookup_Type_Char, cancellationToken)) { if (args.TypedChar == '=') { // They've typed an equals. Cancel existing sessions and potentially start a // new session. EventHookupSessionManager.CancelAndDismissExistingSessions(); if (IsTextualPlusEquals(args.TextView, args.SubjectBuffer)) { EventHookupSessionManager.BeginSession( this, args.TextView, args.SubjectBuffer, _asyncListener, TESTSessionHookupMutex ); } } else { // Spaces are the only non-'=' character that allow the session to continue if (args.TypedChar != ' ') { EventHookupSessionManager.CancelAndDismissExistingSessions(); } } } }
private void HandleTabWorker(ITextView textView, ITextBuffer subjectBuffer, Action nextHandler, CancellationToken cancellationToken) { AssertIsForeground(); // For test purposes only! if (EventHookupSessionManager.CurrentSession.TESTSessionHookupMutex != null) { try { EventHookupSessionManager.CurrentSession.TESTSessionHookupMutex.ReleaseMutex(); } catch (ApplicationException) { } } // Blocking wait (if necessary) to determine whether to consume the tab and // generate the event handler. EventHookupSessionManager.CurrentSession.GetEventNameTask.Wait(cancellationToken); string eventHandlerMethodName = null; if (EventHookupSessionManager.CurrentSession.GetEventNameTask.Status == TaskStatus.RanToCompletion) { eventHandlerMethodName = EventHookupSessionManager.CurrentSession.GetEventNameTask.WaitAndGetResult(cancellationToken); } if (eventHandlerMethodName == null || EventHookupSessionManager.CurrentSession.TextView != textView) { nextHandler(); EventHookupSessionManager.CancelAndDismissExistingSessions(); return; } // If QuickInfoSession is null, then Tab was pressed before the background task // finished (that is, the Wait call above actually needed to wait). Since we know an // event hookup was found, we should set everything up now because the background task // will not have a chance to set things up until after this Tab has been handled, and // by then it's too late. When the background task alerts that it found an event hookup // nothing will change because QuickInfoSession will already be set. EventHookupSessionManager.EventHookupFoundInSession(EventHookupSessionManager.CurrentSession); // This tab means we should generate the event handler method. Begin the code // generation process. GenerateAndAddEventHandler(textView, subjectBuffer, eventHandlerMethodName, nextHandler, cancellationToken); }
public bool ExecuteCommand(EscapeKeyCommandArgs args, CommandExecutionContext context) { AssertIsForeground(); EventHookupSessionManager.CancelAndDismissExistingSessions(); return(false); }
public EventHookupSession( EventHookupSessionManager eventHookupSessionManager, EventHookupCommandHandler commandHandler, ITextView textView, ITextBuffer subjectBuffer, IAsynchronousOperationListener asyncListener, Mutex testSessionHookupMutex) { AssertIsForeground(); _cancellationTokenSource = new CancellationTokenSource(); _textView = textView; _subjectBuffer = subjectBuffer; this.TESTSessionHookupMutex = testSessionHookupMutex; var document = textView.TextSnapshot.GetOpenDocumentInCurrentContextWithChanges(); if (document != null && document.Project.Solution.Workspace.CanApplyChange(ApplyChangesKind.ChangeDocument)) { var position = textView.GetCaretPoint(subjectBuffer).Value.Position; _trackingPoint = textView.TextSnapshot.CreateTrackingPoint(position, PointTrackingMode.Negative); _trackingSpan = textView.TextSnapshot.CreateTrackingSpan(new Span(position, 1), SpanTrackingMode.EdgeInclusive); var asyncToken = asyncListener.BeginAsyncOperation(GetType().Name + ".Start"); this.GetEventNameTask = Task.Factory.SafeStartNewFromAsync( () => DetermineIfEventHookupAndGetHandlerNameAsync(document, position, _cancellationTokenSource.Token), _cancellationTokenSource.Token, TaskScheduler.Default); var continuedTask = this.GetEventNameTask.SafeContinueWith(t => { AssertIsForeground(); if (t.Result != null) { commandHandler.EventHookupSessionManager.EventHookupFoundInSession(this); } }, _cancellationTokenSource.Token, TaskContinuationOptions.OnlyOnRanToCompletion, ForegroundThreadAffinitizedObject.CurrentForegroundThreadData.TaskScheduler); continuedTask.CompletesAsyncOperation(asyncToken); } else { _trackingPoint = textView.TextSnapshot.CreateTrackingPoint(0, PointTrackingMode.Negative); _trackingSpan = textView.TextSnapshot.CreateTrackingSpan(new Span(), SpanTrackingMode.EdgeInclusive); this.GetEventNameTask = SpecializedTasks.Default<string>(); eventHookupSessionManager.CancelAndDismissExistingSessions(); } }
public void ExecuteCommand(EscapeKeyCommandArgs args, Action nextHandler) { AssertIsForeground(); EventHookupSessionManager.CancelAndDismissExistingSessions(); nextHandler(); }
public bool ExecuteCommand(EscapeKeyCommandArgs args, CommandExecutionContext context) { _threadingContext.ThrowIfNotOnUIThread(); EventHookupSessionManager.CancelAndDismissExistingSessions(); return(false); }