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);
            }
        }
Beispiel #5
0
            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();
                }
            }
Beispiel #6
0
        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);
        }
Beispiel #13
0
 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();
                }
            }
Beispiel #15
0
 public void ExecuteCommand(EscapeKeyCommandArgs args, Action nextHandler)
 {
     AssertIsForeground();
     EventHookupSessionManager.CancelAndDismissExistingSessions();
     nextHandler();
 }
 public bool ExecuteCommand(EscapeKeyCommandArgs args, CommandExecutionContext context)
 {
     _threadingContext.ThrowIfNotOnUIThread();
     EventHookupSessionManager.CancelAndDismissExistingSessions();
     return(false);
 }