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; }
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(); } }
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); }
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)); }
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); }
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)); }
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)); }
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); } }
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); } }
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); }
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); }
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(); } }
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); }
/// <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; }
/// <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); }
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); }
internal TestWaitIndicator(IWaitContext waitContext) { _waitContext = waitContext; }
public TestWaitIndicator() { _waitContext = new UncancellableWaitContext(); }
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(); }
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(); } }
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(); } } }
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()); }
internal BasicWaitIndicator(IWaitContext waitContext) { _waitContext = waitContext; }
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; }
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; }
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); }