コード例 #1
0
        private bool Execute(
            ITextBuffer textBuffer,
            ITextView view,
            CancellationToken cancellationToken)
        {
            var spans = view.Selection.GetSnapshotSpansOnBuffer(textBuffer);

            if (spans.Count(s => s.Length > 0) != 1)
            {
                return(false);
            }

            var document = textBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();

            if (document == null)
            {
                return(false);
            }

            var options = document.Project.Solution.Workspace.Options;
            var result  = ExtractMethodService.ExtractMethodAsync(
                document, spans.Single().Span.ToTextSpan(), options, cancellationToken).WaitAndGetResult(cancellationToken);

            Contract.ThrowIfNull(result);

            if (!result.Succeeded && !result.SucceededWithSuggestion)
            {
                // if it failed due to out/ref parameter in async method, try it with different option
                var newResult = TryWithoutMakingValueTypesRef(document, spans, options, result, cancellationToken);
                if (newResult != null)
                {
                    var notificationService = document.Project.Solution.Workspace.Services.GetService <INotificationService>();
                    if (notificationService != null)
                    {
                        if (!notificationService.ConfirmMessageBox(
                                string.Join(Environment.NewLine, result.Reasons) + Environment.NewLine + Environment.NewLine +
                                EditorFeaturesResources.ExtractMethodAsyncErrorFix,
                                EditorFeaturesResources.ExtractMethodFailedReasons, NotificationSeverity.Error))
                        {
                            // We handled the command, displayed a notification and did not produce code.
                            return(true);
                        }
                    }

                    // reset result
                    result = newResult;
                }
                else if (TryNotifyFailureToUser(document, result))
                {
                    // We handled the command, displayed a notification and did not produce code.
                    return(true);
                }
            }

            // apply the change to buffer
            // get method name token
            ApplyChangesToBuffer(result, textBuffer, cancellationToken);

            // start inline rename
            var methodNameAtInvocation  = result.InvocationNameToken;
            var snapshotAfterFormatting = textBuffer.CurrentSnapshot;
            var documentAfterFormatting = snapshotAfterFormatting.GetOpenDocumentInCurrentContextWithChanges();

            _renameService.StartInlineSession(documentAfterFormatting, methodNameAtInvocation.Span, cancellationToken);

            // select invocation span
            view.TryMoveCaretToAndEnsureVisible(new SnapshotPoint(snapshotAfterFormatting, methodNameAtInvocation.Span.End));
            view.SetSelection(
                methodNameAtInvocation.Span.ToSnapshotSpan(snapshotAfterFormatting));

            return(true);
        }
コード例 #2
0
        private static ExtractMethodResult TryWithoutMakingValueTypesRef(
            Document document,
            NormalizedSnapshotSpanCollection spans,
            ExtractMethodResult result,
            CancellationToken cancellationToken
            )
        {
            var options = document.Project.Solution.Options;

            if (
                options.GetOption(
                    ExtractMethodOptions.DontPutOutOrRefOnStruct,
                    document.Project.Language
                    ) || !result.Reasons.IsSingle()
                )
            {
                return(null);
            }

            var reason = result.Reasons.FirstOrDefault();
            var length =
                FeaturesResources.Asynchronous_method_cannot_have_ref_out_parameters_colon_bracket_0_bracket.IndexOf(
                    ':'
                    );

            if (
                reason != null &&
                length > 0 &&
                reason.IndexOf(
                    FeaturesResources.Asynchronous_method_cannot_have_ref_out_parameters_colon_bracket_0_bracket.Substring(
                        0,
                        length
                        ),
                    0,
                    length,
                    StringComparison.Ordinal
                    ) >= 0
                )
            {
                options = options.WithChangedOption(
                    ExtractMethodOptions.DontPutOutOrRefOnStruct,
                    document.Project.Language,
                    true
                    );
                var newResult = ExtractMethodService
                                .ExtractMethodAsync(
                    document,
                    spans.Single().Span.ToTextSpan(),
                    localFunction: false,
                    options,
                    cancellationToken
                    )
                                .WaitAndGetResult(cancellationToken);

                // retry succeeded, return new result
                if (newResult.Succeeded || newResult.SucceededWithSuggestion)
                {
                    return(newResult);
                }
            }

            return(null);
        }
コード例 #3
0
        private bool Execute(
            ITextBuffer textBuffer,
            ITextView view,
            IUIThreadOperationContext waitContext)
        {
            var cancellationToken = waitContext.UserCancellationToken;

            var spans = view.Selection.GetSnapshotSpansOnBuffer(textBuffer);

            if (spans.Count(s => s.Length > 0) != 1)
            {
                return(false);
            }

            var document = textBuffer.CurrentSnapshot.GetFullyLoadedOpenDocumentInCurrentContextWithChanges(
                waitContext, _threadingContext);

            if (document == null)
            {
                return(false);
            }

            var result = ExtractMethodService.ExtractMethodAsync(
                document, spans.Single().Span.ToTextSpan(), localFunction: false, cancellationToken: cancellationToken).WaitAndGetResult(cancellationToken);

            Contract.ThrowIfNull(result);

            if (!result.Succeeded && !result.SucceededWithSuggestion)
            {
                // if it failed due to out/ref parameter in async method, try it with different option
                var newResult = TryWithoutMakingValueTypesRef(document, spans, result, cancellationToken);
                if (newResult != null)
                {
                    var notificationService = document.Project.Solution.Workspace.Services.GetService <INotificationService>();
                    if (notificationService != null)
                    {
                        // We are about to show a modal UI dialog so we should take over the command execution
                        // wait context. That means the command system won't attempt to show its own wait dialog
                        // and also will take it into consideration when measuring command handling duration.
                        waitContext.TakeOwnership();
                        if (!notificationService.ConfirmMessageBox(
                                EditorFeaturesResources.Extract_method_encountered_the_following_issues + Environment.NewLine + Environment.NewLine +
                                string.Join(Environment.NewLine, result.Reasons) + Environment.NewLine + Environment.NewLine +
                                EditorFeaturesResources.We_can_fix_the_error_by_not_making_struct_out_ref_parameter_s_Do_you_want_to_proceed,
                                title: EditorFeaturesResources.Extract_Method,
                                severity: NotificationSeverity.Error))
                        {
                            // We handled the command, displayed a notification and did not produce code.
                            return(true);
                        }
                    }

                    // reset result
                    result = newResult;
                }
                else if (TryNotifyFailureToUser(document, result, waitContext))
                {
                    // We handled the command, displayed a notification and did not produce code.
                    return(true);
                }
            }

            // apply the change to buffer
            // get method name token
            ApplyChangesToBuffer(result, textBuffer, cancellationToken);

            // start inline rename
            var methodNameAtInvocation  = result.InvocationNameToken;
            var snapshotAfterFormatting = textBuffer.CurrentSnapshot;
            var documentAfterFormatting = snapshotAfterFormatting.GetOpenDocumentInCurrentContextWithChanges();

            _renameService.StartInlineSession(documentAfterFormatting, methodNameAtInvocation.Span, cancellationToken);

            // select invocation span
            view.TryMoveCaretToAndEnsureVisible(new SnapshotPoint(snapshotAfterFormatting, methodNameAtInvocation.Span.End));
            view.SetSelection(
                methodNameAtInvocation.Span.ToSnapshotSpan(snapshotAfterFormatting));

            return(true);
        }