Пример #1
0
        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);
        }
Пример #5
0
        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);
                }
            }
        }
Пример #6
0
        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);
            }
        }