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)); }
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); }
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); }
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); }
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); }