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(); } } }
private void ApplyRename(Solution newSolution, IUIThreadOperationContext operationContext) { 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) { // We pass CancellationToken.None here because we don't have a usable token to pass. The IUIThreadOperationContext // passed here as a cancellation token, but the caller in CommitCore has already turned off cancellation // because we're committed to the update at this point. If we ever want to pass cancellation here, we'd want to move this // part back out of this method and before the point where we've already opened a global transaction. var root = newDocument.GetSyntaxRootSynchronously(CancellationToken.None); finalSolution = finalSolution.WithDocumentSyntaxRoot(id, root); } else { var newText = newDocument.GetTextSynchronously(CancellationToken.None); finalSolution = finalSolution.WithDocumentText(id, newText); } // Make sure to include any document rename as well finalSolution = finalSolution.WithDocumentName(id, newDocument.Name); } if (_workspace.TryApplyChanges(finalSolution)) { // Since rename can apply file changes as well, and those file // changes can generate new document ids, include added documents // as well as changed documents. This also ensures that any document // that was removed is not included var finalChanges = _workspace.CurrentSolution.GetChanges(_baseSolution); var finalChangedIds = finalChanges .GetProjectChanges() .SelectMany(c => c.GetChangedDocuments().Concat(c.GetAddedDocuments())) .ToList(); if (!_renameInfo.TryOnAfterGlobalSymbolRenamed(_workspace, finalChangedIds, this.ReplacementText)) { var notificationService = _workspace.Services.GetService <INotificationService>(); operationContext.TakeOwnership(); notificationService.SendNotification( EditorFeaturesResources.Rename_operation_was_not_properly_completed_Some_file_might_not_have_been_updated, EditorFeaturesResources.Rename_Symbol, NotificationSeverity.Information); } undoTransaction.Commit(); } }