private async Task<Tuple<IEnumerable<ReferencedSymbol>, Solution>> FindReferencedSymbolsAsync(Document document, int position, IWaitContext waitContext)
        {
            var cancellationToken = waitContext.CancellationToken;

            var symbol = await SymbolFinder.FindSymbolAtPositionAsync(document, position, cancellationToken: cancellationToken).ConfigureAwait(false);
            if (symbol != null)
            {
                // If this document is not in the primary workspace, we may want to search for results
                // in a solution different from the one we started in. Use the starting workspace's
                // ISymbolMappingService to get a context for searching in the proper solution.
                var mappingService = document.Project.Solution.Workspace.Services.GetService<ISymbolMappingService>();

                var mapping = await mappingService.MapSymbolAsync(document, symbol, cancellationToken).ConfigureAwait(false);
                if (mapping != null)
                {
                    var displayName = mapping.Symbol.IsConstructor() ? mapping.Symbol.ContainingType.Name : mapping.Symbol.Name;

                    waitContext.Message = string.Format(EditorFeaturesResources.FindingReferencesOf, displayName);

                    var result = await SymbolFinder.FindReferencesAsync(mapping.Symbol, mapping.Solution, cancellationToken).ConfigureAwait(false);
                    var searchSolution = mapping.Solution;

                    return Tuple.Create(result, searchSolution);
                }
            }

            return null;
        }
Example #2
0
        private void CommitCore(IWaitContext waitContext, bool previewChanges)
        {
            var eventName = previewChanges
                ? FunctionId.Rename_CommitCoreWithPreview
                : FunctionId.Rename_CommitCore;

            using (
                Logger.LogBlock(
                    eventName,
                    KeyValueLogMessage.Create(LogType.UserAction),
                    waitContext.CancellationToken
                    )
                )
            {
                var newSolution =
                    _conflictResolutionTask.Join(waitContext.CancellationToken).NewSolution;
                waitContext.AllowCancel = false;

                if (previewChanges)
                {
                    var previewService = _workspace.Services.GetService <IPreviewDialogService>();

                    newSolution = previewService.PreviewChanges(
                        string.Format(
                            EditorFeaturesResources.Preview_Changes_0,
                            EditorFeaturesResources.Rename
                            ),
                        "vs.csharp.refactoring.rename",
                        string.Format(
                            EditorFeaturesResources.Rename_0_to_1_colon,
                            this.OriginalSymbolName,
                            this.ReplacementText
                            ),
                        _renameInfo.FullDisplayName,
                        _renameInfo.Glyph,
                        newSolution,
                        _triggerDocument.Project.Solution
                        );

                    if (newSolution == null)
                    {
                        // User clicked cancel.
                        return;
                    }
                }

                // The user hasn't cancelled by now, so we're done waiting for them. Off to
                // rename!
                waitContext.Message = EditorFeaturesResources.Updating_files;

                Dismiss(rollbackTemporaryEdits: true);
                CancelAllOpenDocumentTrackingTasks();

                ApplyRename(newSolution, waitContext);

                LogRenameSession(RenameLogMessage.UserActionOutcome.Committed, previewChanges);

                EndRenameSession();
            }
        }
Example #3
0
        public bool TryFindReferences(Document document, int position, IWaitContext waitContext)
        {
            var cancellationToken = waitContext.CancellationToken;

            var result = this.FindReferencedSymbolsAsync(document, position, waitContext).WaitAndGetResult(cancellationToken);
            return TryDisplayReferences(result);
        }
Example #4
0
        private async Task <Tuple <IEnumerable <ReferencedSymbol>, Solution> > FindReferencedSymbolsAsync(
            Document document, int position, IWaitContext waitContext)
        {
            var cancellationToken = waitContext.CancellationToken;

            var symbolAndProject = await FindUsagesHelpers.GetRelevantSymbolAndProjectAtPositionAsync(
                document, position, cancellationToken).ConfigureAwait(false);

            if (symbolAndProject == null)
            {
                return(null);
            }

            var symbol  = symbolAndProject?.symbol;
            var project = symbolAndProject?.project;

            var displayName = FindUsagesHelpers.GetDisplayName(symbol);

            waitContext.Message = string.Format(
                EditorFeaturesResources.Finding_references_of_0, displayName);

            var result = await SymbolFinder.FindReferencesAsync(symbol, project.Solution, cancellationToken).ConfigureAwait(false);

            return(Tuple.Create(result, project.Solution));
        }
Example #5
0
        private async Task ResetInteractiveAsync(
            IVsInteractiveWindow vsInteractiveWindow,
            ImmutableArray <string> referencePaths,
            ImmutableArray <string> referenceSearchPaths,
            ImmutableArray <string> sourceSearchPaths,
            ImmutableArray <string> namespacesToImport,
            string projectDirectory,
            IWaitContext waitContext)
        {
            // First, open the repl window.
            var engine = (InteractiveEvaluator)vsInteractiveWindow.InteractiveWindow.Evaluator;

            // If the user hits the cancel button on the wait indicator, then we want to stop the
            // build.
            waitContext.CancellationToken.Register(() =>
                                                   _dte.ExecuteCommand("Build.Cancel"), useSynchronizationContext: true);

            // First, start a build
            await BuildProject().ConfigureAwait(true);

            // Then reset the REPL
            waitContext.Message = ServicesVSResources.ResettingInteractive;
            await vsInteractiveWindow.InteractiveWindow.Operations.ResetAsync(initialize : false).ConfigureAwait(true);

            // Now send the reference paths we've collected to the repl.
            await engine.SetPathsAsync(referenceSearchPaths, sourceSearchPaths, projectDirectory).ConfigureAwait(true);

            await vsInteractiveWindow.InteractiveWindow.SubmitAsync(new[]
            {
                referencePaths.Select(_createReference).Join("\r\n"),
                namespacesToImport.Select(_createImport).Join("\r\n")
            }).ConfigureAwait(true);
        }
Example #6
0
        public bool TryFindReferences(Document document, int position, IWaitContext waitContext)
        {
            var cancellationToken = waitContext.CancellationToken;

            var result = this.FindReferencedSymbolsAsync(document, position, waitContext).WaitAndGetResult(cancellationToken);

            return(TryDisplayReferences(result));
        }
Example #7
0
        private async Task ResetInteractiveAsync(
            IInteractiveWindow interactiveWindow,
            ImmutableArray <string> referencePaths,
            ImmutableArray <string> referenceSearchPaths,
            ImmutableArray <string> sourceSearchPaths,
            ImmutableArray <string> projectNamespaces,
            string projectDirectory,
            IWaitContext waitContext)
        {
            // First, open the repl window.
            IInteractiveEvaluator evaluator = interactiveWindow.Evaluator;

            // If the user hits the cancel button on the wait indicator, then we want to stop the
            // build.
            using (waitContext.CancellationToken.Register(() =>
                                                          CancelBuildProject(), useSynchronizationContext: true))
            {
                // First, start a build.
                // If the build fails do not reset the REPL.
                var builtSuccessfully = await BuildProject().ConfigureAwait(true);

                if (!builtSuccessfully)
                {
                    return;
                }
            }

            // Then reset the REPL
            waitContext.Message = InteractiveEditorFeaturesResources.Resetting_Interactive;
            await interactiveWindow.Operations.ResetAsync(initialize : true).ConfigureAwait(true);

            // TODO: load context from an rsp file.

            // Now send the reference paths we've collected to the repl.
            // The SetPathsAsync method is not available through an Interface.
            // Execute the method only if the cast to a concrete InteractiveEvaluator succeeds.
            InteractiveEvaluator interactiveEvaluator = evaluator as InteractiveEvaluator;

            if (interactiveEvaluator != null)
            {
                await interactiveEvaluator.SetPathsAsync(referenceSearchPaths, sourceSearchPaths, projectDirectory).ConfigureAwait(true);
            }

            var editorOptions           = _editorOptionsFactoryService.GetOptions(interactiveWindow.CurrentLanguageBuffer);
            var importReferencesCommand = referencePaths.Select(_createReference);
            await interactiveWindow.SubmitAsync(importReferencesCommand).ConfigureAwait(true);

            // Project's default namespace might be different from namespace used within project.
            // Filter out namespace imports that do not exist in interactive compilation.
            IEnumerable <string> namespacesToImport = await GetNamespacesToImportAsync(projectNamespaces, interactiveWindow).ConfigureAwait(true);

            var importNamespacesCommand = namespacesToImport.Select(_createImport).Join(editorOptions.GetNewLineCharacter());

            if (!string.IsNullOrWhiteSpace(importNamespacesCommand))
            {
                await interactiveWindow.SubmitAsync(new[] { importNamespacesCommand }).ConfigureAwait(true);
            }
        }
        public bool TryFindReferences(Document document, int position, IWaitContext waitContext)
        {
            var cancellationToken = waitContext.CancellationToken;

            // Otherwise, fall back to displaying SymbolFinder based references.
            var result = this.FindReferencedSymbolsAsync(document, position, waitContext).WaitAndGetResult(cancellationToken);

            return(TryDisplayReferences(result));
        }
Example #9
0
        private async Task ResetInteractiveAsync(
            IInteractiveWindow interactiveWindow,
            ImmutableArray<string> referencePaths,
            ImmutableArray<string> referenceSearchPaths,
            ImmutableArray<string> sourceSearchPaths,
            ImmutableArray<string> projectNamespaces,
            string projectDirectory,
            IWaitContext waitContext)
        {
            // First, open the repl window.
            IInteractiveEvaluator evaluator = interactiveWindow.Evaluator;

            // If the user hits the cancel button on the wait indicator, then we want to stop the
            // build.
            using (waitContext.CancellationToken.Register(() =>
                CancelBuildProject(), useSynchronizationContext: true))
            {
                // First, start a build.
                // If the build fails do not reset the REPL.
                var builtSuccessfully = await BuildProject().ConfigureAwait(true);
                if (!builtSuccessfully)
                {
                    return;
                }
            }

            // Then reset the REPL
            waitContext.Message = InteractiveEditorFeaturesResources.Resetting_Interactive;
            await interactiveWindow.Operations.ResetAsync(initialize: true).ConfigureAwait(true);

            // TODO: load context from an rsp file.

            // Now send the reference paths we've collected to the repl.
            // The SetPathsAsync method is not available through an Interface.
            // Execute the method only if the cast to a concrete InteractiveEvaluator succeeds.
            InteractiveEvaluator interactiveEvaluator = evaluator as InteractiveEvaluator;
            if (interactiveEvaluator != null)
            {
                await interactiveEvaluator.SetPathsAsync(referenceSearchPaths, sourceSearchPaths, projectDirectory).ConfigureAwait(true);
            }

            var editorOptions = _editorOptionsFactoryService.GetOptions(interactiveWindow.CurrentLanguageBuffer);
            var importReferencesCommand = referencePaths.Select(_createReference);
            await interactiveWindow.SubmitAsync(importReferencesCommand).ConfigureAwait(true);

            // Project's default namespace might be different from namespace used within project.
            // Filter out namespace imports that do not exist in interactive compilation.
            IEnumerable<string> namespacesToImport = await GetNamespacesToImportAsync(projectNamespaces, interactiveWindow).ConfigureAwait(true);
            var importNamespacesCommand = namespacesToImport.Select(_createImport).Join(editorOptions.GetNewLineCharacter());

            if (!string.IsNullOrWhiteSpace(importNamespacesCommand))
            {
                await interactiveWindow.SubmitAsync(new[] { importNamespacesCommand }).ConfigureAwait(true);
            }
        }
Example #10
0
        private void ApplyRename(Solution newSolution, IWaitContext waitContext)
        {
            var changes            = _baseSolution.GetChanges(newSolution);
            var changedDocumentIDs = changes.GetProjectChanges().SelectMany(c => c.GetChangedDocuments()).ToList();

            if (!_renameInfo.TryOnBeforeGlobalSymbolRenamed(_workspace, changedDocumentIDs, this.ReplacementText))
            {
                var notificationService = _workspace.Services.GetService <INotificationService>();
                notificationService.SendNotification(
                    EditorFeaturesResources.Rename_operation_was_cancelled_or_is_not_valid,
                    EditorFeaturesResources.Rename_Symbol,
                    NotificationSeverity.Error);
                return;
            }

            using (var undoTransaction = _workspace.OpenGlobalUndoTransaction(EditorFeaturesResources.Inline_Rename))
            {
                var finalSolution = newSolution.Workspace.CurrentSolution;
                foreach (var id in changedDocumentIDs)
                {
                    // If the document supports syntax tree, then create the new solution from the
                    // updated syntax root.  This should ensure that annotations are preserved, and
                    // prevents the solution from having to reparse documents when we already have
                    // the trees for them.  If we don't support syntax, then just use the text of
                    // the document.
                    var newDocument = newSolution.GetDocument(id);
                    if (newDocument.SupportsSyntaxTree)
                    {
                        var root = newDocument.GetSyntaxRootSynchronously(waitContext.CancellationToken);
                        finalSolution = finalSolution.WithDocumentSyntaxRoot(id, root);
                    }
                    else
                    {
                        var newText = newDocument.GetTextAsync(waitContext.CancellationToken).WaitAndGetResult(waitContext.CancellationToken);
                        finalSolution = finalSolution.WithDocumentText(id, newText);
                    }
                }

                if (_workspace.TryApplyChanges(finalSolution))
                {
                    if (!_renameInfo.TryOnAfterGlobalSymbolRenamed(_workspace, changedDocumentIDs, this.ReplacementText))
                    {
                        var notificationService = _workspace.Services.GetService <INotificationService>();
                        notificationService.SendNotification(
                            EditorFeaturesResources.Rename_operation_was_not_properly_completed_Some_file_might_not_have_been_updated,
                            EditorFeaturesResources.Rename_Symbol,
                            NotificationSeverity.Information);
                    }

                    undoTransaction.Commit();
                }
            }
        }
        /// <summary>
        /// Finds references using <see cref="SymbolFinder.FindReferencesAsync(ISymbol, Solution, CancellationToken)"/>
        /// </summary>
        private async Task AddSymbolReferencesAsync(Document document, int position, ArrayBuilder<INavigableItem> builder, IWaitContext waitContext)
        {
            var result = await this.FindReferencedSymbolsAsync(document, position, waitContext).ConfigureAwait(false);
            if (result != null)
            {
                var referencedSymbols = result.Item1;
                var searchSolution = result.Item2;

                var q = from r in referencedSymbols
                        from loc in r.Locations
                        select NavigableItemFactory.GetItemFromSymbolLocation(searchSolution, r.Definition, loc.Location);

                builder.AddRange(q);
            }
        }
Example #12
0
        private async Task ResetInteractiveAsync(
            IInteractiveWindow interactiveWindow,
            ImmutableArray <string> referencePaths,
            ImmutableArray <string> referenceSearchPaths,
            ImmutableArray <string> sourceSearchPaths,
            ImmutableArray <string> namespacesToImport,
            string projectDirectory,
            IWaitContext waitContext)
        {
            // First, open the repl window.
            IInteractiveEvaluator evaluator = interactiveWindow.Evaluator;

            // If the user hits the cancel button on the wait indicator, then we want to stop the
            // build.
            waitContext.CancellationToken.Register(() =>
                                                   CancelBuildProject(), useSynchronizationContext: true);

            // First, start a build.
            // If the build fails do not reset the REPL.
            var builtSuccessfully = await BuildProject().ConfigureAwait(true);

            if (!builtSuccessfully)
            {
                return;
            }

            // Then reset the REPL
            waitContext.Message = InteractiveEditorFeaturesResources.ResettingInteractive;
            await interactiveWindow.Operations.ResetAsync(initialize : true).ConfigureAwait(true);

            // TODO: load context from an rsp file.

            // Now send the reference paths we've collected to the repl.
            // The SetPathsAsync method is not available through an Interface.
            // Execute the method only if the cast to a concrete InteractiveEvaluator succeeds.
            InteractiveEvaluator interactiveEvaluator = evaluator as InteractiveEvaluator;

            if (interactiveEvaluator != null)
            {
                await interactiveEvaluator.SetPathsAsync(referenceSearchPaths, sourceSearchPaths, projectDirectory).ConfigureAwait(true);
            }

            await interactiveWindow.SubmitAsync(new[]
            {
                referencePaths.Select(_createReference).Join("\r\n"),
                namespacesToImport.Select(_createImport).Join("\r\n")
            }).ConfigureAwait(true);
        }
Example #13
0
        private async Task ResetInteractiveAsync(
            IInteractiveWindow interactiveWindow,
            ImmutableArray<string> referencePaths,
            ImmutableArray<string> referenceSearchPaths,
            ImmutableArray<string> sourceSearchPaths,
            ImmutableArray<string> namespacesToImport,
            string projectDirectory,
            IWaitContext waitContext)
        {
            // First, open the repl window.
            IInteractiveEvaluator evaluator = interactiveWindow.Evaluator;

            // If the user hits the cancel button on the wait indicator, then we want to stop the
            // build.
            waitContext.CancellationToken.Register(() =>
                CancelBuildProject(), useSynchronizationContext: true);

            // First, start a build.
            // If the build fails do not reset the REPL.
            var builtSuccessfully = await BuildProject().ConfigureAwait(true);
            if (!builtSuccessfully)
            {
                return;
            }

            // Then reset the REPL
            waitContext.Message = InteractiveEditorFeaturesResources.ResettingInteractive;
            await interactiveWindow.Operations.ResetAsync(initialize: true).ConfigureAwait(true);

            // TODO: load context from an rsp file.

            // Now send the reference paths we've collected to the repl.
            // The SetPathsAsync method is not available through an Interface.
            // Execute the method only if the cast to a concrete InteractiveEvaluator succeeds.
            InteractiveEvaluator interactiveEvaluator = evaluator as InteractiveEvaluator;
            if (interactiveEvaluator != null)
            {
                await interactiveEvaluator.SetPathsAsync(referenceSearchPaths, sourceSearchPaths, projectDirectory).ConfigureAwait(true);
            }

            await interactiveWindow.SubmitAsync(new[]
            {
                referencePaths.Select(_createReference).Join("\r\n"),
                namespacesToImport.Select(_createImport).Join("\r\n")
            }).ConfigureAwait(true);
        }
        public bool TryFindReferences(Document document, int position, IWaitContext waitContext)
        {
            var cancellationToken = waitContext.CancellationToken;

            var result = this.FindReferencedSymbolsAsync(document, position, waitContext).WaitAndGetResult(cancellationToken);
            if (result != null && result.Item1 != null)
            {
                var searchSolution = result.Item2;
                foreach (var presenter in _presenters)
                {
                    presenter.DisplayResult(searchSolution, result.Item1);
                    return true;
                }
            }

            return false;
        }
        public bool TryFindReferences(Document document, int position, IWaitContext waitContext)
        {
            var cancellationToken = waitContext.CancellationToken;

            var result = this.FindReferencedSymbolsAsync(document, position, waitContext).WaitAndGetResult(cancellationToken);

            if (result != null && result.Item1 != null)
            {
                var searchSolution = result.Item2;
                foreach (var presenter in _presenters)
                {
                    presenter.DisplayResult(searchSolution, result.Item1);
                    return(true);
                }
            }

            return(false);
        }
Example #16
0
        private void CommitCore(IWaitContext waitContext, bool previewChanges)
        {
            using (Logger.LogBlock(previewChanges ? FunctionId.Rename_CommitCoreWithPreview : FunctionId.Rename_CommitCore, waitContext.CancellationToken))
            {
                _conflictResolutionTask.Wait(waitContext.CancellationToken);
                waitContext.AllowCancel = false;

                Solution newSolution = _conflictResolutionTask.Result.NewSolution;
                if (previewChanges)
                {
                    var previewService = _workspace.Services.GetService <IPreviewDialogService>();

                    newSolution = previewService.PreviewChanges(
                        string.Format(EditorFeaturesResources.PreviewChangesOf, EditorFeaturesResources.Rename),
                        "vs.csharp.refactoring.rename",
                        string.Format(EditorFeaturesResources.RenameToTitle, this.OriginalSymbolName, _renameInfo.GetFinalSymbolName(this.ReplacementText)),
                        _renameInfo.FullDisplayName,
                        _renameInfo.Glyph,
                        _conflictResolutionTask.Result.NewSolution,
                        _triggerDocument.Project.Solution);

                    if (newSolution == null)
                    {
                        // User clicked cancel.
                        return;
                    }
                }

                // The user hasn't cancelled by now, so we're done waiting for them. Off to
                // rename!
                waitContext.Message = EditorFeaturesResources.UpdatingFiles;

                DismissAndRollbackTemporaryEdits();
                CancelAllOpenDocumentTrackingTasks();

                ApplyRename(newSolution, waitContext);

                LogRenameSession(RenameLogMessage.UserActionOutcome.Committed, previewChanges);

                RenameTrackingDismisser.DismissRenameTracking(_workspace, _workspace.GetOpenDocumentIds());
                _inlineRenameSessionDurationLogBlock.Dispose();
            }
        }
Example #17
0
        public bool TryFindReferences(Document document, int position, IWaitContext waitContext)
        {
            var cancellationToken = waitContext.CancellationToken;
            var workspace         = document.Project.Solution.Workspace;

            // First see if we have any external navigable item references.
            // If so, we display the results as navigable items.
            var succeeded = TryFindAndDisplayNavigableItemsReferencesAsync(document, position, waitContext).WaitAndGetResult(cancellationToken);

            if (succeeded)
            {
                return(true);
            }

            // Otherwise, fall back to displaying SymbolFinder based references.
            var result = this.FindReferencedSymbolsAsync(document, position, waitContext).WaitAndGetResult(cancellationToken);

            return(TryDisplayReferences(result));
        }
        public async Task<IEnumerable<INavigableItem>> FindReferencesAsync(Document document, int position, IWaitContext waitContext)
        {
            var cancellationToken = waitContext.CancellationToken;
            var result = await this.FindReferencedSymbolsAsync(document, position, waitContext).ConfigureAwait(false);
            if (result == null)
            {
                return SpecializedCollections.EmptyEnumerable<INavigableItem>();
            }

            var referencedSymbols = result.Item1;
            var searchSolution = result.Item2;

            var q = from r in referencedSymbols
                    from loc in r.Locations
                    select NavigableItemFactory.GetItemFromSymbolLocation(searchSolution, r.Definition, loc.Location);

            // realize the list here so that the consumer await'ing the result doesn't lazily cause
            // them to be created on an inappropriate thread.
            return q.ToList();
        }
        private async Task<Tuple<IEnumerable<ReferencedSymbol>, Solution>> FindReferencedSymbolsAsync(
            Document document, int position, IWaitContext waitContext)
        {
            var cancellationToken = waitContext.CancellationToken;

            var symbolAndSolution = await GetRelevantSymbolAndSolutionAtPositionAsync(document, position, cancellationToken).ConfigureAwait(false);
            if (symbolAndSolution == null)
            {
                return null;
            }

            var symbol = symbolAndSolution.Item1;
            var solution = symbolAndSolution.Item2;

            var displayName = GetDisplayName(symbol);

            waitContext.Message = string.Format(
                EditorFeaturesResources.Finding_references_of_0, displayName);

            var result = await SymbolFinder.FindReferencesAsync(symbol, solution, cancellationToken).ConfigureAwait(false);

            return Tuple.Create(result, solution);
        }
        private async Task <Tuple <IEnumerable <ReferencedSymbol>, Solution> > FindReferencedSymbolsAsync(
            Document document, int position, IWaitContext waitContext)
        {
            var cancellationToken = waitContext.CancellationToken;

            var symbolAndSolution = await GetRelevantSymbolAndSolutionAtPositionAsync(document, position, cancellationToken).ConfigureAwait(false);

            if (symbolAndSolution == null)
            {
                return(null);
            }

            var symbol   = symbolAndSolution.Item1;
            var solution = symbolAndSolution.Item2;

            var displayName = symbol.IsConstructor() ? symbol.ContainingType.Name : symbol.Name;

            waitContext.Message = string.Format(
                EditorFeaturesResources.Finding_references_of_0, displayName);

            var result = await SymbolFinder.FindReferencesAsync(symbol, solution, cancellationToken).ConfigureAwait(false);

            return(Tuple.Create(result, solution));
        }
        private bool Execute(EncapsulateFieldCommandArgs args, IWaitContext waitContext)
        {
            var text = args.TextView.TextBuffer.CurrentSnapshot.AsText();
            var cancellationToken = waitContext.CancellationToken;

            if (!Workspace.TryGetWorkspace(text.Container, out var workspace))
            {
                return(false);
            }

            var documentId = workspace.GetDocumentIdInCurrentContext(text.Container);

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

            var document = workspace.CurrentSolution.GetDocument(documentId);

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

            var spans = args.TextView.Selection.GetSnapshotSpansOnBuffer(args.SubjectBuffer);

            var service = document.GetLanguageService <AbstractEncapsulateFieldService>();

            var result = service.EncapsulateFieldAsync(document, spans.First().Span.ToTextSpan(), true, cancellationToken).WaitAndGetResult(cancellationToken);

            if (result == null)
            {
                var notificationService = workspace.Services.GetService <INotificationService>();
                notificationService.SendNotification(EditorFeaturesResources.Please_select_the_definition_of_the_field_to_encapsulate, severity: NotificationSeverity.Error);
                return(false);
            }

            waitContext.AllowCancel = false;

            var finalSolution = result.GetSolutionAsync(cancellationToken).WaitAndGetResult(cancellationToken);

            var previewService = workspace.Services.GetService <IPreviewDialogService>();

            if (previewService != null)
            {
                finalSolution = previewService.PreviewChanges(
                    string.Format(EditorFeaturesResources.Preview_Changes_0, EditorFeaturesResources.Encapsulate_Field),
                    "vs.csharp.refactoring.preview",
                    EditorFeaturesResources.Encapsulate_Field_colon,
                    result.GetNameAsync(cancellationToken).WaitAndGetResult(cancellationToken),
                    result.GetGlyphAsync(cancellationToken).WaitAndGetResult(cancellationToken),
                    finalSolution,
                    document.Project.Solution);
            }

            if (finalSolution == null)
            {
                // User clicked cancel.
                return(true);
            }

            using (var undoTransaction = _undoManager.GetTextBufferUndoManager(args.SubjectBuffer).TextBufferUndoHistory.CreateTransaction(EditorFeaturesResources.Encapsulate_Field))
            {
                if (!workspace.TryApplyChanges(finalSolution))
                {
                    undoTransaction.Cancel();
                    return(false);
                }

                undoTransaction.Complete();
            }

            return(true);
        }
Example #22
0
        /// <summary>
        /// Finds references using <see cref="SymbolFinder.FindReferencesAsync(ISymbol, Solution, CancellationToken)"/>
        /// </summary>
        private async Task AddSymbolReferencesAsync(Document document, int position, ArrayBuilder <INavigableItem> builder, IWaitContext waitContext)
        {
            var result = await this.FindReferencedSymbolsAsync(document, position, waitContext).ConfigureAwait(false);

            if (result != null)
            {
                var referencedSymbols = result.Item1;
                var searchSolution    = result.Item2;

                var q = from r in referencedSymbols
                        from loc in r.Locations
                        select NavigableItemFactory.GetItemFromSymbolLocation(searchSolution, r.Definition, loc.Location);

                builder.AddRange(q);
            }
        }
        /// <summary>
        /// Attempts to find and display navigable item references, including the references provided by external providers.
        /// </summary>
        /// <returns>False if there are no external references or display was not successful.</returns>
        private async Task<bool> TryFindAndDisplayNavigableItemsReferencesAsync(Document document, int position, IWaitContext waitContext)
        {
            var foundReferences = false;
            if (_externalReferencesProviders.Any())
            {
                var cancellationToken = waitContext.CancellationToken;
                var builder = ArrayBuilder<INavigableItem>.GetInstance();
                await AddExternalReferencesAsync(document, position, builder, cancellationToken).ConfigureAwait(false);

                // TODO: Merging references from SymbolFinder and external providers might lead to duplicate or counter-intuitive results.
                // TODO: For now, we avoid merging and just display the results either from SymbolFinder or the external result providers but not both.
                if (builder.Count > 0 && TryDisplayReferences(builder))
                {
                    foundReferences = true;
                }

                builder.Free();
            }

            return foundReferences;
        }
Example #24
0
        /// <summary>
        /// Attempts to find and display navigable item references, including the references provided by external providers.
        /// </summary>
        /// <returns>False if there are no external references or display was not successful.</returns>
        private async Task <bool> TryFindAndDisplayNavigableItemsReferencesAsync(Document document, int position, IWaitContext waitContext)
        {
            var foundReferences = false;

            if (_externalReferencesProviders.Any())
            {
                var cancellationToken = waitContext.CancellationToken;
                var builder           = ArrayBuilder <INavigableItem> .GetInstance();
                await AddExternalReferencesAsync(document, position, builder, cancellationToken).ConfigureAwait(false);

                // TODO: Merging references from SymbolFinder and external providers might lead to duplicate or counter-intuitive results.
                // TODO: For now, we avoid merging and just display the results either from SymbolFinder or the external result providers but not both.
                if (builder.Count > 0 && TryDisplayReferences(builder))
                {
                    foundReferences = true;
                }

                builder.Free();
            }

            return(foundReferences);
        }
Example #25
0
        private async Task <Tuple <IEnumerable <ReferencedSymbol>, Solution> > FindReferencedSymbolsAsync(Document document, int position, IWaitContext waitContext)
        {
            var cancellationToken = waitContext.CancellationToken;

            var symbol = await SymbolFinder.FindSymbolAtPositionAsync(document, position, cancellationToken : cancellationToken).ConfigureAwait(false);

            if (symbol != null)
            {
                // If this document is not in the primary workspace, we may want to search for results
                // in a solution different from the one we started in. Use the starting workspace's
                // ISymbolMappingService to get a context for searching in the proper solution.
                var mappingService = document.Project.Solution.Workspace.Services.GetService <ISymbolMappingService>();

                var mapping = await mappingService.MapSymbolAsync(document, symbol, cancellationToken).ConfigureAwait(false);

                if (mapping != null)
                {
                    var displayName = mapping.Symbol.IsConstructor() ? mapping.Symbol.ContainingType.Name : mapping.Symbol.Name;

                    waitContext.Message = string.Format(EditorFeaturesResources.FindingReferencesOf, displayName);

                    var result = await SymbolFinder.FindReferencesAsync(mapping.Symbol, mapping.Solution, cancellationToken).ConfigureAwait(false);

                    var searchSolution = mapping.Solution;

                    return(Tuple.Create(result, searchSolution));
                }
            }

            return(null);
        }
Example #26
0
 internal TestWaitIndicator(IWaitContext waitContext)
 {
     _waitContext = waitContext;
 }
Example #27
0
 public TestWaitIndicator()
 {
     _waitContext = new UncancellableWaitContext();
 }
Example #28
0
        private Task ResetInteractiveAsync(
            IVsInteractiveWindow vsInteractiveWindow,
            List <string> referencePaths,
            List <string> referenceSearchPaths,
            List <string> sourceSearchPaths,
            List <string> namespacesToImport,
            string projectDirectory,
            IWaitContext waitContext)
        {
            // First, open the repl window.
            var engine = (InteractiveEvaluator)vsInteractiveWindow.InteractiveWindow.Evaluator;

            var uiTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();

            // If the user hits the cancel button on the wait indicator, then we want to stop the
            // build.
            waitContext.CancellationToken.Register(() =>
                                                   _dte.ExecuteCommand("Build.Cancel"), useSynchronizationContext: true);

            // First, start a build.
            var buildTask = BuildProject();

            // Then reset the repl.
            var resetTask = buildTask.SafeContinueWithFromAsync(_ =>
            {
                waitContext.Message = ServicesVSResources.ResettingInteractive;
                return(vsInteractiveWindow.InteractiveWindow.Operations.ResetAsync(initialize: false));
            },
                                                                waitContext.CancellationToken,
                                                                TaskContinuationOptions.OnlyOnRanToCompletion,
                                                                uiTaskScheduler);

            // Now send the reference paths we've collected to the repl.
            var submitReferencesTask = resetTask.SafeContinueWith(
                _ =>
            {
                // TODO (tomat): In general, these settings should be applied again when we auto-reset.

                engine.SetInitialPaths(
                    referenceSearchPaths.ToArray(),
                    sourceSearchPaths.ToArray(),
                    projectDirectory);

                vsInteractiveWindow.InteractiveWindow.SubmitAsync(new[]
                {
                    // TODO(DustinCa): Update these to be language agnostic.
                    referencePaths.Select(_createReference).Join("\r\n"),
                    namespacesToImport.Select(_createImport).Join("\r\n")
                });
            },
                waitContext.CancellationToken,
                TaskContinuationOptions.OnlyOnRanToCompletion,
                uiTaskScheduler);

            return(submitReferencesTask);

            //// TODO (tomat): Ideally we should check if the imported namespaces are available in #r'd assemblies.
            //// We should wait until #r submission is finished and then query for existing namespaces.

            ////if (namespacesToImport.IsEmpty())
            ////{
            ////    return submitReferencesTask;
            ////}

            ////var submitReferencesAndUsingsTask = submitReferencesTask.SafeContinueWith(
            ////    _ =>
            ////    {
            ////        var compilation = engine.GetPreviousSubmissionProject().GetCompilation(waitContext.CancellationToken);

            ////        replWindow.Submit(new[]
            ////        {
            ////            (from ns in namespacesToImport
            ////             where compilation.GlobalNamespace.GetMembers(ns, waitContext.CancellationToken).Any()
            ////             select string.Format("using {0};", ns)).Join("\r\n")
            ////        });
            ////    },
            ////    waitContext.CancellationToken,
            ////    TaskContinuationOptions.OnlyOnRanToCompletion,
            ////    uiTaskScheduler);

            //// return submitReferencesAndUsingsTask;
        }
        public async Task<IEnumerable<INavigableItem>> FindReferencesAsync(Document document, int position, IWaitContext waitContext)
        {
            var cancellationToken = waitContext.CancellationToken;

            var builder = ArrayBuilder<INavigableItem>.GetInstance();
            await AddExternalReferencesAsync(document, position, builder, cancellationToken).ConfigureAwait(false);

            // TODO: Merging references from SymbolFinder and external providers might lead to duplicate or counter-intuitive results.
            // TODO: For now, we avoid merging and just display the results either from SymbolFinder or the external result providers but not both.
            if (builder.Count == 0)
            {
                await AddSymbolReferencesAsync(document, position, builder, waitContext).ConfigureAwait(false);
            }

            // realize the list here so that the consumer await'ing the result doesn't lazily cause
            // them to be created on an inappropriate thread.
            return builder.ToArrayAndFree();
        }
Example #30
0
        private void CommitCore(IWaitContext waitContext, bool previewChanges)
        {
            using (Logger.LogBlock(previewChanges ? FunctionId.Rename_CommitCoreWithPreview : FunctionId.Rename_CommitCore, waitContext.CancellationToken))
            {
                _conflictResolutionTask.Wait(waitContext.CancellationToken);
                waitContext.AllowCancel = false;

                Solution newSolution = _conflictResolutionTask.Result.NewSolution;
                if (previewChanges)
                {
                    var previewService = _workspace.Services.GetService<IPreviewDialogService>();

                    newSolution = previewService.PreviewChanges(
                        string.Format(EditorFeaturesResources.Preview_Changes_0, EditorFeaturesResources.Rename),
                        "vs.csharp.refactoring.rename",
                        string.Format(EditorFeaturesResources.Rename_0_to_1_colon, this.OriginalSymbolName, _renameInfo.GetFinalSymbolName(this.ReplacementText)),
                        _renameInfo.FullDisplayName,
                        _renameInfo.Glyph,
                        _conflictResolutionTask.Result.NewSolution,
                        _triggerDocument.Project.Solution);

                    if (newSolution == null)
                    {
                        // User clicked cancel.
                        return;
                    }
                }

                // The user hasn't cancelled by now, so we're done waiting for them. Off to
                // rename!
                waitContext.Message = EditorFeaturesResources.Updating_files;

                Dismiss(rollbackTemporaryEdits: true);
                CancelAllOpenDocumentTrackingTasks();

                ApplyRename(newSolution, waitContext);

                LogRenameSession(RenameLogMessage.UserActionOutcome.Committed, previewChanges);

                EndRenameSession();
            }
        }
Example #31
0
        private void ApplyRename(Solution newSolution, IWaitContext waitContext)
        {
            var changes = _baseSolution.GetChanges(newSolution);
            var changedDocumentIDs = changes.GetProjectChanges().SelectMany(c => c.GetChangedDocuments()).ToList();

            if (!_renameInfo.TryOnBeforeGlobalSymbolRenamed(_workspace, changedDocumentIDs, this.ReplacementText))
            {
                var notificationService = _workspace.Services.GetService<INotificationService>();
                notificationService.SendNotification(
                    EditorFeaturesResources.Rename_operation_was_cancelled_or_is_not_valid,
                    EditorFeaturesResources.Rename_Symbol,
                    NotificationSeverity.Error);
                return;
            }

            using (var undoTransaction = _workspace.OpenGlobalUndoTransaction(EditorFeaturesResources.Inline_Rename))
            {
                var finalSolution = newSolution.Workspace.CurrentSolution;
                foreach (var id in changedDocumentIDs)
                {
                    // If the document supports syntax tree, then create the new solution from the
                    // updated syntax root.  This should ensure that annotations are preserved, and
                    // prevents the solution from having to reparse documents when we already have
                    // the trees for them.  If we don't support syntax, then just use the text of
                    // the document.
                    var newDocument = newSolution.GetDocument(id);
                    if (newDocument.SupportsSyntaxTree)
                    {
                        var root = newDocument.GetSyntaxRootSynchronously(waitContext.CancellationToken);
                        finalSolution = finalSolution.WithDocumentSyntaxRoot(id, root);
                    }
                    else
                    {
                        var newText = newDocument.GetTextAsync(waitContext.CancellationToken).WaitAndGetResult(waitContext.CancellationToken);
                        finalSolution = finalSolution.WithDocumentText(id, newText);
                    }
                }

                if (_workspace.TryApplyChanges(finalSolution))
                {
                    if (!_renameInfo.TryOnAfterGlobalSymbolRenamed(_workspace, changedDocumentIDs, this.ReplacementText))
                    {
                        var notificationService = _workspace.Services.GetService<INotificationService>();
                        notificationService.SendNotification(
                            EditorFeaturesResources.Rename_operation_was_not_properly_completed_Some_file_might_not_have_been_updated,
                            EditorFeaturesResources.Rename_Symbol,
                            NotificationSeverity.Information);
                    }

                    undoTransaction.Commit();
                }
            }
        }
Example #32
0
 public VSTypeScriptWaitContextWrapper(IWaitContext underlyingObject)
 => _underlyingObject = underlyingObject;
        public bool TryFindReferences(Document document, int position, IWaitContext waitContext)
        {
            var cancellationToken = waitContext.CancellationToken;
            var workspace = document.Project.Solution.Workspace;

            // First see if we have any external navigable item references.
            // If so, we display the results as navigable items.
            var succeeded = TryFindAndDisplayNavigableItemsReferencesAsync(document, position, waitContext).WaitAndGetResult(cancellationToken);
            if (succeeded)
            {
                return true;
            }

            // Otherwise, fall back to displaying SymbolFinder based references.
            var result = this.FindReferencedSymbolsAsync(document, position, waitContext).WaitAndGetResult(cancellationToken);
            return TryDisplayReferences(result);
        }
        public async Task <IEnumerable <INavigableItem> > FindReferencesAsync(Document document, int position, IWaitContext waitContext)
        {
            var cancellationToken = waitContext.CancellationToken;
            var result            = await this.FindReferencedSymbolsAsync(document, position, waitContext).ConfigureAwait(false);

            if (result == null)
            {
                return(SpecializedCollections.EmptyEnumerable <INavigableItem>());
            }

            var referencedSymbols = result.Item1;
            var searchSolution    = result.Item2;

            var q = from r in referencedSymbols
                    from loc in r.Locations
                    select NavigableItemFactory.GetItemFromSymbolLocation(searchSolution, r.Definition, loc.Location);

            // realize the list here so that the consumer await'ing the result doesn't lazily cause
            // them to be created on an inapropriate thread.
            return(q.ToList());
        }
Example #35
0
 internal BasicWaitIndicator(IWaitContext waitContext)
 {
     _waitContext = waitContext;
 }
Example #36
0
        public async Task <IEnumerable <INavigableItem> > FindReferencesAsync(Document document, int position, IWaitContext waitContext)
        {
            var cancellationToken = waitContext.CancellationToken;

            var builder = ArrayBuilder <INavigableItem> .GetInstance();

            await AddExternalReferencesAsync(document, position, builder, cancellationToken).ConfigureAwait(false);

            // TODO: Merging references from SymbolFinder and external providers might lead to duplicate or counter-intuitive results.
            // TODO: For now, we avoid merging and just display the results either from SymbolFinder or the external result providers but not both.
            if (builder.Count == 0)
            {
                await AddSymbolReferencesAsync(document, position, builder, waitContext).ConfigureAwait(false);
            }

            // realize the list here so that the consumer await'ing the result doesn't lazily cause
            // them to be created on an inappropriate thread.
            return(builder.ToArrayAndFree());
        }
 internal SimpleWaitIndicator(IWaitContext waitContext)
 {
     _waitContext = waitContext;
 }
Example #38
0
        private Task ResetInteractiveAsync(
            IVsInteractiveWindow vsInteractiveWindow,
            List<string> referencePaths,
            List<string> referenceSearchPaths,
            List<string> sourceSearchPaths,
            List<string> namespacesToImport,
            string projectDirectory,
            IWaitContext waitContext)
        {
            // First, open the repl window.
            var engine = (InteractiveEvaluator)vsInteractiveWindow.InteractiveWindow.Evaluator;

            var uiTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();

            // If the user hits the cancel button on the wait indicator, then we want to stop the
            // build.
            waitContext.CancellationToken.Register(() =>
                _dte.ExecuteCommand("Build.Cancel"), useSynchronizationContext: true);

            // First, start a build.
            var buildTask = BuildProject();

            // Then reset the repl.
            var resetTask = buildTask.SafeContinueWithFromAsync(_ =>
                {
                    waitContext.Message = ServicesVSResources.ResettingInteractive;
                    return vsInteractiveWindow.InteractiveWindow.Operations.ResetAsync(initialize: false);
                },
                waitContext.CancellationToken,
                TaskContinuationOptions.OnlyOnRanToCompletion,
                uiTaskScheduler);

            // Now send the reference paths we've collected to the repl.
            var submitReferencesTask = resetTask.SafeContinueWith(
                _ =>
                {
                    // TODO (tomat): In general, these settings should be applied again when we auto-reset.

                    engine.SetInitialPaths(
                        referenceSearchPaths.ToArray(),
                        sourceSearchPaths.ToArray(),
                        projectDirectory);

                    vsInteractiveWindow.InteractiveWindow.Submit(new[]
                    {
                        // TODO(DustinCa): Update these to be language agnostic.
                        referencePaths.Select(_createReference).Join("\r\n"),
                        namespacesToImport.Select(_createImport).Join("\r\n")
                    });
                },
                waitContext.CancellationToken,
                TaskContinuationOptions.OnlyOnRanToCompletion,
                uiTaskScheduler);

            return submitReferencesTask;

            //// TODO (tomat): Ideally we should check if the imported namespaces are available in #r'd assemblies.
            //// We should wait until #r submission is finished and then query for existing namespaces.

            ////if (namespacesToImport.IsEmpty()) 
            ////{
            ////    return submitReferencesTask;
            ////}

            ////var submitReferencesAndUsingsTask = submitReferencesTask.SafeContinueWith(
            ////    _ =>
            ////    {
            ////        var compilation = engine.GetPreviousSubmissionProject().GetCompilation(waitContext.CancellationToken);

            ////        replWindow.Submit(new[] 
            ////        { 
            ////            (from ns in namespacesToImport
            ////             where compilation.GlobalNamespace.GetMembers(ns, waitContext.CancellationToken).Any()
            ////             select string.Format("using {0};", ns)).Join("\r\n")
            ////        });
            ////    },
            ////    waitContext.CancellationToken,
            ////    TaskContinuationOptions.OnlyOnRanToCompletion,
            ////    uiTaskScheduler);

            //// return submitReferencesAndUsingsTask;
        }
Example #39
0
 internal TestWaitIndicator(IWaitContext waitContext)
 {
     _waitContext = waitContext;
 }
        private async Task ResetInteractiveAsync(
            IVsInteractiveWindow vsInteractiveWindow,
            ImmutableArray<string> referencePaths,
            ImmutableArray<string> referenceSearchPaths,
            ImmutableArray<string> sourceSearchPaths,
            ImmutableArray<string> namespacesToImport,
            string projectDirectory,
            IWaitContext waitContext)
        {
            // First, open the repl window.
            var engine = (InteractiveEvaluator)vsInteractiveWindow.InteractiveWindow.Evaluator;

            // If the user hits the cancel button on the wait indicator, then we want to stop the
            // build.
            waitContext.CancellationToken.Register(() =>
                _dte.ExecuteCommand("Build.Cancel"), useSynchronizationContext: true);

            // First, start a build
            await BuildProject().ConfigureAwait(true);

            // Then reset the REPL
            waitContext.Message = ServicesVSResources.ResettingInteractive;
            await vsInteractiveWindow.InteractiveWindow.Operations.ResetAsync(initialize: false).ConfigureAwait(true);

            // Now send the reference paths we've collected to the repl.
            await engine.SetPathsAsync(referenceSearchPaths, sourceSearchPaths, projectDirectory).ConfigureAwait(true);

            await vsInteractiveWindow.InteractiveWindow.SubmitAsync(new[]
            {
                referencePaths.Select(_createReference).Join("\r\n"),
                namespacesToImport.Select(_createImport).Join("\r\n")
            }).ConfigureAwait(true);
        }