private static async Task PopulateModificationsAsync(
            ModifiedFileResponse modification,
            OmniSharpWorkspace workspace,
            IDictionary <string, List <LinePositionSpanTextChange> > modifications)
        {
            foreach (var change in modification.Changes)
            {
                var(filename, _) = await change.TranslateAsync(workspace, modification.FileName);

                if (change.StartLine < 0)
                {
                    continue;
                }

                if (modifications.TryGetValue(filename, out var changes))
                {
                    changes.Add(change);
                }
                else
                {
                    modifications.Add(filename, new List <LinePositionSpanTextChange>
                    {
                        change
                    });
                }
            }
        }
        public async Task <IActionResult> Rename([FromBody] RenameRequest request)
        {
            _workspace.EnsureBufferUpdated(request);

            var response = new RenameResponse();

            var documentId = _workspace.GetDocumentId(request.FileName);

            if (documentId != null)
            {
                var document   = _workspace.CurrentSolution.GetDocument(documentId);
                var sourceText = await document.GetTextAsync();

                var position = sourceText.Lines.GetPosition(new LinePosition(request.Line - 1, request.Column));

                var symbol = await SymbolFinder.FindSymbolAtPositionAsync(document, position);

                Solution solution = _workspace.CurrentSolution;

                if (symbol != null)
                {
                    solution = await Renamer.RenameSymbolAsync(solution, symbol, request.RenameTo, _workspace.Options);
                }

                var changes = new List <ModifiedFileResponse>();

                var solutionChanges = solution.GetChanges(_workspace.CurrentSolution);

                foreach (var projectChange in solutionChanges.GetProjectChanges())
                {
                    foreach (var changedDocumentId in projectChange.GetChangedDocuments())
                    {
                        var changedDocument = solution.GetDocument(changedDocumentId);
                        var changedText     = await changedDocument.GetTextAsync();

                        var modifiedFileResponse = new ModifiedFileResponse(changedDocument.FilePath, changedText.ToString());

                        changes.Add(modifiedFileResponse);
                    }
                }

                // Attempt to update the workspace
                if (_workspace.TryApplyChanges(solution))
                {
                    response.Changes = changes;
                }
            }

            return(new ObjectResult(response));
        }
Ejemplo n.º 3
0
        public static async Task <IEnumerable <ModifiedFileResponse> > GetFileChangesAsync(Solution newSolution, Solution oldSolution, string newFileDirectory, bool wantTextChanges)
        {
            var changes         = new Dictionary <string, ModifiedFileResponse>();
            var solutionChanges = newSolution.GetChanges(oldSolution);

            foreach (var projectChange in solutionChanges.GetProjectChanges())
            {
                foreach (var changedDocumentId in projectChange.GetAddedDocuments())
                {
                    var document = newSolution.GetDocument(changedDocumentId);
                    var source   = await document.GetTextAsync();

                    var modifiedFileResponse = new ModifiedFileResponse(document.Name);
                    var change = new LinePositionSpanTextChange();
                    change.NewText = source.ToString();
                    var newPath = Path.Combine(newFileDirectory, document.Name);
                    modifiedFileResponse.FileName = newPath;
                    modifiedFileResponse.Changes  = new[] { change };
                    changes[newPath] = modifiedFileResponse;

                    // This is a little weird. The added document doesn't have a filepath
                    // and we need one so that future operations on this document work
                    var id           = DocumentId.CreateNewId(document.Project.Id);
                    var version      = VersionStamp.Create();
                    var documentInfo = DocumentInfo.Create(id, document.Name, filePath: newPath, loader: TextLoader.From(TextAndVersion.Create(source, version)));

                    var workspace = newSolution.Workspace as OmnisharpWorkspace;
                    workspace.RemoveDocument(changedDocumentId);
                    workspace.AddDocument(documentInfo);
                }

                foreach (var changedDocumentId in projectChange.GetChangedDocuments())
                {
                    var changedDocument = newSolution.GetDocument(changedDocumentId);
                    ModifiedFileResponse modifiedFileResponse;
                    var filePath = changedDocument.FilePath;

                    if (!changes.TryGetValue(filePath, out modifiedFileResponse))
                    {
                        modifiedFileResponse = new ModifiedFileResponse(filePath);
                        changes[filePath]    = modifiedFileResponse;
                    }

                    if (!wantTextChanges)
                    {
                        var changedText = await changedDocument.GetTextAsync();

                        modifiedFileResponse.Buffer = changedText.ToString();
                    }
                    else
                    {
                        var originalDocument = oldSolution.GetDocument(changedDocumentId);
                        IEnumerable <TextChange> textChanges;
                        textChanges = await changedDocument.GetTextChangesAsync(originalDocument);

                        var linePositionSpanTextChanges = await LinePositionSpanTextChange.Convert(originalDocument, textChanges);

                        modifiedFileResponse.Changes = modifiedFileResponse.Changes != null
                            ? modifiedFileResponse.Changes.Union(linePositionSpanTextChanges)
                            : linePositionSpanTextChanges;
                    }
                }
            }
            return(changes.Values);
        }
Ejemplo n.º 4
0
        public async Task <RenameResponse> Rename(RenameRequest request)
        {
            var response = new RenameResponse();

            var document = _workspace.GetDocument(request.FileName);

            if (document != null)
            {
                var sourceText = await document.GetTextAsync();

                var position = sourceText.Lines.GetPosition(new LinePosition(request.Line - 1, request.Column - 1));

                var symbol = await SymbolFinder.FindSymbolAtPositionAsync(document, position);

                Solution solution = _workspace.CurrentSolution;

                if (symbol != null)
                {
                    try
                    {
                        solution = await Renamer.RenameSymbolAsync(solution, symbol, request.RenameTo, _workspace.Options);
                    }
                    catch (ArgumentException e)
                    {
                        response.ErrorMessage = e.Message;
                    }
                }

                var changes         = new Dictionary <string, ModifiedFileResponse>();
                var solutionChanges = solution.GetChanges(_workspace.CurrentSolution);

                foreach (var projectChange in solutionChanges.GetProjectChanges())
                {
                    foreach (var changedDocumentId in projectChange.GetChangedDocuments())
                    {
                        var changedDocument = solution.GetDocument(changedDocumentId);

                        ModifiedFileResponse modifiedFileResponse;
                        if (!changes.TryGetValue(changedDocument.FilePath, out modifiedFileResponse))
                        {
                            modifiedFileResponse = new ModifiedFileResponse(changedDocument.FilePath);
                            changes[changedDocument.FilePath] = modifiedFileResponse;
                        }

                        if (!request.WantsTextChanges)
                        {
                            var changedText = await changedDocument.GetTextAsync();

                            modifiedFileResponse.Buffer = changedText.ToString();
                        }
                        else
                        {
                            var originalDocument = _workspace.CurrentSolution.GetDocument(changedDocumentId);
                            var textChanges      = await changedDocument.GetTextChangesAsync(originalDocument);

                            var linePositionSpanTextChanges = await LinePositionSpanTextChange.Convert(originalDocument, textChanges);

                            modifiedFileResponse.Changes = modifiedFileResponse.Changes != null
                                ? modifiedFileResponse.Changes.Union(linePositionSpanTextChanges)
                                : linePositionSpanTextChanges;
                        }
                    }
                }

                if (request.ApplyTextChanges)
                {
                    // Attempt to update the workspace
                    if (_workspace.TryApplyChanges(solution))
                    {
                        response.Changes = changes.Values;
                    }
                }
                else
                {
                    response.Changes = changes.Values;
                }
            }

            return(response);
        }
Ejemplo n.º 5
0
        private async Task <IEnumerable <ModifiedFileResponse> > GetFileChangesAsync(Solution newSolution, Solution oldSolution, string directory, bool wantTextChanges)
        {
            var filePathToResponseMap = new Dictionary <string, ModifiedFileResponse>();
            var solutionChanges       = newSolution.GetChanges(oldSolution);

            foreach (var projectChange in solutionChanges.GetProjectChanges())
            {
                // Handle added documents
                foreach (var documentId in projectChange.GetAddedDocuments())
                {
                    var newDocument = newSolution.GetDocument(documentId);
                    var text        = await newDocument.GetTextAsync();

                    var newFilePath = newDocument.FilePath == null || !Path.IsPathRooted(newDocument.FilePath)
                        ? Path.Combine(directory, newDocument.Name)
                        : newDocument.FilePath;

                    var modifiedFileResponse = new ModifiedFileResponse(newFilePath)
                    {
                        Changes = new[] {
                            new LinePositionSpanTextChange
                            {
                                NewText = text.ToString()
                            }
                        }
                    };

                    filePathToResponseMap[newFilePath] = modifiedFileResponse;

                    // We must add new files to the workspace to ensure that they're present when the host editor
                    // tries to modify them. This is a strange interaction because the workspace could be left
                    // in an incomplete state if the host editor doesn't apply changes to the new file, but it's
                    // what we've got today.
                    if (this.Workspace.GetDocument(newFilePath) == null)
                    {
                        var fileInfo = new FileInfo(newFilePath);
                        if (!fileInfo.Exists)
                        {
                            fileInfo.CreateText().Dispose();
                        }
                        else
                        {
                            // The file already exists on disk? Ensure that it's zero-length. If so, we can still use it.
                            if (fileInfo.Length > 0)
                            {
                                Logger.LogError($"File already exists on disk: '{newFilePath}'");
                                break;
                            }
                        }

                        this.Workspace.AddDocument(projectChange.ProjectId, newFilePath, newDocument.SourceCodeKind);
                    }
                    else
                    {
                        // The file already exists in the workspace? We're in a bad state.
                        Logger.LogError($"File already exists in workspace: '{newFilePath}'");
                    }
                }

                // Handle changed documents
                foreach (var documentId in projectChange.GetChangedDocuments())
                {
                    var newDocument = newSolution.GetDocument(documentId);
                    var filePath    = newDocument.FilePath;

                    if (!filePathToResponseMap.TryGetValue(filePath, out var modifiedFileResponse))
                    {
                        modifiedFileResponse            = new ModifiedFileResponse(filePath);
                        filePathToResponseMap[filePath] = modifiedFileResponse;
                    }

                    if (wantTextChanges)
                    {
                        var oldDocument = oldSolution.GetDocument(documentId);
                        var linePositionSpanTextChanges = await TextChanges.GetAsync(newDocument, oldDocument);

                        modifiedFileResponse.Changes = modifiedFileResponse.Changes != null
                            ? modifiedFileResponse.Changes.Union(linePositionSpanTextChanges)
                            : linePositionSpanTextChanges;
                    }
                    else
                    {
                        var text = await newDocument.GetTextAsync();

                        modifiedFileResponse.Buffer = text.ToString();
                    }
                }
            }

            return(filePathToResponseMap.Values);
        }
Ejemplo n.º 6
0
        public async Task <RenameResponse> Handle(RenameRequest request)
        {
            var response = new RenameResponse();

            var document = _workspace.GetDocument(request.FileName);

            if (document != null)
            {
                var sourceText = await document.GetTextAsync();

                var position = sourceText.GetTextPosition(request);

                var symbol = await SymbolFinder.FindSymbolAtPositionAsync(document, position);

                Solution solution = _workspace.CurrentSolution;

                if (symbol != null)
                {
                    var options = new OmniSharpRenameOptions(
                        RenameOverloads: _omniSharpOptions.RenameOptions.RenameOverloads,
                        RenameInStrings: _omniSharpOptions.RenameOptions.RenameInStrings,
                        RenameInComments: _omniSharpOptions.RenameOptions.RenameInComments);

                    (solution, response.ErrorMessage) = await OmniSharpRenamer.RenameSymbolAsync(solution, symbol, request.RenameTo, options, nonConflictSymbols : null, CancellationToken.None);

                    if (response.ErrorMessage is not null)
                    {
                        // An error occurred. There are no changes to report.
                        return(response);
                    }
                }

                var changes         = new Dictionary <string, ModifiedFileResponse>();
                var solutionChanges = solution.GetChanges(_workspace.CurrentSolution);

                foreach (var projectChange in solutionChanges.GetProjectChanges())
                {
                    foreach (var changedDocumentId in projectChange.GetChangedDocuments())
                    {
                        var changedDocument = solution.GetDocument(changedDocumentId);

                        if (!changes.TryGetValue(changedDocument.FilePath, out var modifiedFileResponse))
                        {
                            modifiedFileResponse = new ModifiedFileResponse(changedDocument.FilePath);
                            changes[changedDocument.FilePath] = modifiedFileResponse;
                        }

                        if (!request.WantsTextChanges)
                        {
                            var changedText = await changedDocument.GetTextAsync();

                            modifiedFileResponse.Buffer = changedText.ToString();
                        }
                        else
                        {
                            var originalDocument            = _workspace.CurrentSolution.GetDocument(changedDocumentId);
                            var linePositionSpanTextChanges = await TextChanges.GetAsync(changedDocument, originalDocument);

                            modifiedFileResponse.Changes = modifiedFileResponse.Changes != null
                                ? modifiedFileResponse.Changes.Union(linePositionSpanTextChanges)
                                : linePositionSpanTextChanges;
                        }
                    }
                }

                if (request.ApplyTextChanges)
                {
                    // Attempt to update the workspace
                    if (_workspace.TryApplyChanges(solution))
                    {
                        response.Changes = changes.Values;
                    }
                }
                else
                {
                    response.Changes = changes.Values;
                }
            }

            return(response);
        }