private Task <bool> RenameAsync(string oldFilePath, string newFilePath, bool isCaseSensitive, string oldName, string newName, ISymbol?symbol, string renameOperationName, CancellationToken token) { token.ThrowIfCancellationRequested(); return(_unconfiguredProjectTasksService.LoadedProjectAsync(async() => { // Perform the rename operation Solution?renamedSolution = await GetRenamedSolutionAsync(oldName, oldFilePath, newFilePath, isCaseSensitive, GetCurrentProject, token); if (renamedSolution is null) { return false; } string rqName = RQName.From(symbol); Solution?solution = GetCurrentProject()?.Solution; if (solution is null) { return false; } IEnumerable <ProjectChanges> changes = renamedSolution.GetChanges(solution).GetProjectChanges(); DTE?dte = _dte.Value; Assumes.NotNull(dte); using var undo = UndoScope.Create(dte, renameOperationName); // Notify other VS features that symbol is about to be renamed NotifyBeforeRename(newName, rqName, changes); // Try and apply the changes to the current solution token.ThrowIfCancellationRequested(); if (!_roslynServices.ApplyChangesToSolution(renamedSolution.Workspace, renamedSolution)) { return false; } // Notify other VS features that symbol has been renamed NotifyAfterRename(newName, rqName, changes); return true; })); }
public override async Task RenameAsync(Project myNewProject, string oldFileName, string newFileName) { Solution renamedSolution = await GetRenamedSolutionAsync(myNewProject, oldFileName, newFileName).ConfigureAwait(false); if (renamedSolution == null) { return; } await _threadingService.SwitchToUIThread(); var renamedSolutionApplied = _roslynServices.ApplyChangesToSolution(myNewProject.Solution.Workspace, renamedSolution); if (!renamedSolutionApplied) { string failureMessage = string.Format(CultureInfo.CurrentCulture, VSResources.RenameSymbolFailed, oldFileName); await _threadingService.SwitchToUIThread(); _userNotificationServices.NotifyFailure(failureMessage); } }
public override async Task RenameAsync(IProjectTreeActionHandlerContext context, IProjectTree node, string value) { Requires.NotNull(context, nameof(Context)); Requires.NotNull(node, nameof(node)); Requires.NotNullOrEmpty(value, nameof(value)); string?oldFilePath = node.FilePath; string oldName = Path.GetFileNameWithoutExtension(oldFilePath); string newFileWithExtension = value; CodeAnalysis.Project?project = GetCurrentProject(); // Rename the file await CPSRenameAsync(context, node, value); if (await IsAutomationFunctionAsync() || node.IsFolder || _vsOnlineServices.ConnectedToVSOnline || FileChangedExtension(oldFilePath, newFileWithExtension)) { // Do not display rename Prompt return; } if (project is null) { return; } string newName = Path.GetFileNameWithoutExtension(newFileWithExtension); if (!await CanRenameTypeAsync(project, oldName, newName)) { return; } (bool result, Renamer.RenameDocumentActionSet? documentRenameResult) = await GetRenameSymbolsActionsAsync(project, oldFilePath, newFileWithExtension); if (!result || documentRenameResult == null) { return; } // Ask if the user wants to rename the symbol bool userWantsToRenameSymbol = await CheckUserConfirmationAsync(oldName); if (!userWantsToRenameSymbol) { return; } _threadingService.RunAndForget(async() => { Solution currentSolution = await PublishLatestSolutionAsync(); string renameOperationName = string.Format(CultureInfo.CurrentCulture, VSResources.Renaming_Type_from_0_to_1, oldName, value); WaitIndicatorResult <Solution> indicatorResult = _waitService.Run( title: VSResources.Renaming_Type, message: renameOperationName, allowCancel: true, token => documentRenameResult.UpdateSolutionAsync(currentSolution, token)); // Do not warn the user if the rename was cancelled by the user if (indicatorResult.IsCancelled) { return; } await _projectVsServices.ThreadingService.SwitchToUIThread(); if (_roslynServices.ApplyChangesToSolution(currentSolution.Workspace, indicatorResult.Result)) { return; } string failureMessage = string.Format(CultureInfo.CurrentCulture, VSResources.RenameSymbolFailed, oldName); _userNotificationServices.ShowWarning(failureMessage); }, _unconfiguredProject); }
public override async Task RenameAsync(IProjectTreeActionHandlerContext context, IProjectTree node, string value) { Requires.NotNull(context, nameof(Context)); Requires.NotNull(node, nameof(node)); Requires.NotNullOrEmpty(value, nameof(value)); string?oldFilePath = node.FilePath; string oldName = Path.GetFileNameWithoutExtension(oldFilePath); string newFileWithExtension = value; CodeAnalysis.Project?project = GetCurrentProject(); // Rename the file await CPSRenameAsync(context, node, value); if (await IsAutomationFunctionAsync() || node.IsFolder || _vsOnlineServices.ConnectedToVSOnline) { // Do not display rename Prompt return; } if (project is null) { return; } string newName = Path.GetFileNameWithoutExtension(newFileWithExtension); if (!await CanRenameType(project, oldName, newName)) { return; } (bool result, Renamer.RenameDocumentActionSet? documentRenameResult) = await GetRenameSymbolsActions(project, oldFilePath, newFileWithExtension); if (result == false || documentRenameResult == null) { return; } // Ask if the user wants to rename the symbol bool userWantsToRenameSymbol = await CheckUserConfirmation(oldName); if (!userWantsToRenameSymbol) { return; } _threadingService.RunAndForget(async() => { // TODO - implement PublishAsync() to sync with LanguageService // https://github.com/dotnet/project-system/issues/3425) // await _languageService.PublishAsync(treeVersion); IVsOperationProgressStageStatus stageStatus = (await _operationProgressService.GetValueAsync()).GetStageStatus(CommonOperationProgressStageIds.Intellisense); await stageStatus.WaitForCompletionAsync(); // Apply actions and notify other VS features CodeAnalysis.Solution?currentSolution = GetCurrentProject()?.Solution; if (currentSolution == null) { return; } string renameOperationName = string.Format(CultureInfo.CurrentCulture, VSResources.Renaming_Type_from_0_to_1, oldName, value); (WaitIndicatorResult result, CodeAnalysis.Solution renamedSolution) = _waitService.WaitForAsyncFunctionWithResult( title: VSResources.Renaming_Type, message: renameOperationName, allowCancel: true, token => documentRenameResult.UpdateSolutionAsync(currentSolution, token)); // Do not warn the user if the rename was cancelled by the user if (result.WasCanceled()) { return; } await _projectVsServices.ThreadingService.SwitchToUIThread(); if (!_roslynServices.ApplyChangesToSolution(currentSolution.Workspace, renamedSolution)) { string failureMessage = string.Format(CultureInfo.CurrentCulture, VSResources.RenameSymbolFailed, oldName); _userNotificationServices.ShowWarning(failureMessage); } return; }, _unconfiguredProject); }
public async Task RenameAsync(Project myNewProject) { Document newDocument = (from d in myNewProject.Documents where StringComparers.Paths.Equals(d.FilePath, _newFilePath) select d).FirstOrDefault(); if (newDocument == null) { return; } var root = await newDocument.GetSyntaxRootAsync().ConfigureAwait(false); if (root == null) { return; } string oldName = Path.GetFileNameWithoutExtension(_oldFilePath); string newName = Path.GetFileNameWithoutExtension(newDocument.FilePath); var declaration = root.DescendantNodes().Where(n => HasMatchingSyntaxNode(newDocument, n, oldName)).FirstOrDefault(); if (declaration == null) { return; } var semanticModel = await newDocument.GetSemanticModelAsync().ConfigureAwait(false); if (semanticModel == null) { return; } var symbol = semanticModel.GetDeclaredSymbol(declaration); if (symbol == null) { return; } var userConfirmed = true; await _threadingService.SwitchToUIThread(); var userNeedPrompt = _optionsSettings.GetPropertiesValue("Environment", "ProjectsAndSolution", "PromptForRenameSymbol", false); if (userNeedPrompt) { string renamePromptMessage = string.Format(Resources.RenameSymbolPrompt, oldName); await _threadingService.SwitchToUIThread(); userConfirmed = _userNotificationServices.Confirm(renamePromptMessage); } if (userConfirmed) { var renamedSolution = await _roslynServices.RenameSymbolAsync(newDocument.Project.Solution, symbol, newName).ConfigureAwait(false); await _threadingService.SwitchToUIThread(); var renamedSolutionApplied = _roslynServices.ApplyChangesToSolution(newDocument.Project.Solution.Workspace, renamedSolution); if (!renamedSolutionApplied) { string failureMessage = string.Format(Resources.RenameSymbolFailed, oldName); await _threadingService.SwitchToUIThread(); _userNotificationServices.NotifyFailure(failureMessage); } } }
internal async Task HandleRenameAsync(string oldFilePath, string newFilePath) { // Do not offer to rename types if the user changes the file extensions if (!oldFilePath.EndsWith(Path.GetExtension(newFilePath), StringComparison.OrdinalIgnoreCase)) { return; } if (GetCurrentProject() is null) { return; } // see if the current project contains a compilation (bool success, bool isCaseSensitive) = await TryDetermineIfCompilationIsCaseSensitiveAsync(GetCurrentProject()); if (!success) { return; } // Check that the new name is a valid identifier in the current programming language string oldName = Path.GetFileNameWithoutExtension(oldFilePath); string newName = Path.GetFileNameWithoutExtension(newFilePath); if (!CanHandleRename(oldName, newName, isCaseSensitive)) { return; } // Check if there are any symbols that need to be renamed ISymbol?symbol = await TryGetSymbolToRename(oldName, oldFilePath, newFilePath, isCaseSensitive, GetCurrentProject); if (symbol is null) { return; } // Ask if the user wants to rename the symbol bool userConfirmed = await CheckUserConfirmation(oldName); if (!userConfirmed) { return; } // Try and apply the changes to the current solution await _projectVsServices.ThreadingService.SwitchToUIThread(); string renameOperationName = string.Format(CultureInfo.CurrentCulture, VSResources.Renaming_Type_from_0_to_1, oldName, newName); (WaitIndicatorResult result, bool renamedSolutionApplied) = _waitService.WaitForAsyncFunctionWithResult( title: VSResources.Renaming_Type, message: renameOperationName, allowCancel: true, async token => { token.ThrowIfCancellationRequested(); return(await _unconfiguredProjectTasksService.LoadedProjectAsync(async() => { // Perform the rename operation Solution?renamedSolution = await GetRenamedSolutionAsync(oldName, oldFilePath, newFilePath, isCaseSensitive, GetCurrentProject, token); if (renamedSolution is null) { return false; } string rqName = RQName.From(symbol); Solution?solution = GetCurrentProject()?.Solution; if (solution is null) { return false; } IEnumerable <ProjectChanges> changes = renamedSolution.GetChanges(solution).GetProjectChanges(); using UndoScope undo = await UndoScope.CreateAsync(_dte, _projectVsServices.ThreadingService, renameOperationName, token); // Notify other VS features that symbol is about to be renamed await NotifyBeforeRename(newName, rqName, changes); // Try and apply the changes to the current solution token.ThrowIfCancellationRequested(); bool applyChangesSucceeded = _roslynServices.ApplyChangesToSolution(renamedSolution.Workspace, renamedSolution); if (applyChangesSucceeded) { // Notify other VS features that symbol has been renamed await NotifyAfterRename(newName, rqName, changes); } return applyChangesSucceeded; })); }); // Do not warn the user if the rename was cancelled by the user if (result.WasCanceled()) { return; } // Notify the user if the rename could not be performed if (!renamedSolutionApplied) { string failureMessage = string.Format(CultureInfo.CurrentCulture, VSResources.RenameSymbolFailed, oldName); _userNotificationServices.ShowWarning(failureMessage); } Project?GetCurrentProject() { foreach (Project proj in _workspace.CurrentSolution.Projects) { if (StringComparers.Paths.Equals(proj.FilePath, _projectVsServices.Project.FullPath)) { return(proj); } } return(null); } }