Example #1
0
        public static async Task <IEnumerable <LinePositionSpanTextChange> > GetFormattingChanges(Document document, int start, int end, OmniSharpOptions omnisharpOptions, ILoggerFactory loggerFactory)
        {
            var optionSet = omnisharpOptions.FormattingOptions.EnableEditorConfigSupport
                ? await document.Project.Solution.Workspace.Options.WithEditorConfigOptions(document.FilePath, loggerFactory)
                : document.Project.Solution.Workspace.Options;

            var newDocument = await Formatter.FormatAsync(document, TextSpan.FromBounds(start, end), optionSet);

            return(await TextChanges.GetAsync(newDocument, document));
        }
Example #2
0
        public async Task <RunCodeActionResponse> Handle(RunCodeActionRequest request)
        {
            var actions = new List <CodeAction>();
            var context = await GetContext(request, actions);

            await GetContextualCodeActions(context);

            if (request.CodeAction > actions.Count())
            {
                return(new RunCodeActionResponse());
            }

            var action = actions.ElementAt(request.CodeAction);

            var operations = await action.GetOperationsAsync(CancellationToken.None);

            foreach (var o in operations)
            {
                o.Apply(_workspace, CancellationToken.None);
            }

            var oldDocument = context.Value.Document;
            var newDocument = _workspace.CurrentSolution.GetDocument(oldDocument.Id);

            var response = new RunCodeActionResponse();

            if (!request.WantsTextChanges)
            {
                // return the text of the new document
                var newText = await newDocument.GetTextAsync();

                response.Text = newText.ToString();
            }
            else
            {
                // return the text changes
                response.Changes = await TextChanges.GetAsync(newDocument, oldDocument);
            }

            return(response);
        }
Example #3
0
        public async Task <FixUsingsResponse> Handle(FixUsingsRequest request)
        {
            var response = new FixUsingsResponse();

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

            if (oldDocument != null)
            {
                var fixUsingsResponse = await new FixUsingsWorker(_providers)
                                        .FixUsingsAsync(oldDocument);

                response.AmbiguousResults = fixUsingsResponse.AmbiguousResults;

                if (request.ApplyTextChanges)
                {
                    _workspace.TryApplyChanges(fixUsingsResponse.Document.Project.Solution);
                }

                var newDocument = fixUsingsResponse.Document;

                if (!request.WantsTextChanges)
                {
                    // return the text of the new document
                    var newText = await newDocument.GetTextAsync();

                    response.Buffer = newText.ToString();
                }
                else
                {
                    // return the text changes
                    response.Changes = await TextChanges.GetAsync(newDocument, oldDocument);
                }
            }

            return(response);
        }
Example #4
0
        // public static async Task<IEnumerable<LinePositionSpanTextChange>> GetFormattingChangesAfterKeystroke(Document document, int position, char character)
        // {
        //     if (character == '\n')
        //     {
        //         // format previous line on new line
        //         var text = await document.GetTextAsync();
        //         var lines = text.Lines;
        //         var targetLine = lines[lines.GetLineFromPosition(position).LineNumber - 1];
        //         if (!string.IsNullOrWhiteSpace(targetLine.Text.ToString(targetLine.Span)))
        //         {
        //             return await GetFormattingChanges(document, targetLine.Start, targetLine.End);
        //         }
        //     }
        //     else if (character == '}' || character == ';')
        //     {
        //         // format after ; and }
        //         var root = await document.GetSyntaxRootAsync();
        //         var node = FindFormatTarget(root, position);
        //         if (node != null)
        //         {
        //             return await GetFormattingChanges(document, node.FullSpan.Start, node.FullSpan.End);
        //         }
        //     }

        //     return Enumerable.Empty<LinePositionSpanTextChange>();
        // }

        // public static SyntaxNode FindFormatTarget(SyntaxNode root, int position)
        // {
        //     // todo@jo - refine this
        //     var token = root.FindToken(position);

        //     if (token.IsKind(SyntaxKind.EndOfFileToken))
        //     {
        //         token = token.GetPreviousToken();
        //     }

        //     switch (token.Kind())
        //     {
        //         // ; -> use the statement
        //         case SyntaxKind.SemicolonToken:
        //             return token.Parent;

        //         // } -> use the parent of the {}-block or
        //         // just the parent (XYZDeclaration etc)
        //         case SyntaxKind.CloseBraceToken:
        //             var parent = token.Parent;
        //             return parent.IsKind(SyntaxKind.Block)
        //                 ? parent.Parent
        //                 : parent;

        //         case SyntaxKind.CloseParenToken:
        //             if (token.GetPreviousToken().IsKind(SyntaxKind.SemicolonToken) &&
        //                 token.Parent.IsKind(SyntaxKind.ForStatement))
        //             {
        //                 return token.Parent;
        //             }

        //             break;
        //     }

        //     return null;
        // }

        // public static async Task<IEnumerable<LinePositionSpanTextChange>> GetFormattingChanges(Document document, int start, int end)
        // {
        //     var newDocument = await Formatter.FormatAsync(document, TextSpan.FromBounds(start, end), document.Project.Solution.Workspace.Options);

        //     return await TextChanges.GetAsync(newDocument, document);
        // }

        // public static async Task<string> GetFormattedText(Document document)
        // {
        //     var newDocument = await Formatter.FormatAsync(document, document.Project.Solution.Workspace.Options);
        //     var text = await newDocument.GetTextAsync();

        //     return text.ToString();
        // }

        public static async Task <IEnumerable <LinePositionSpanTextChange> > GetFormattedTextChanges(Document document)
        {
            var newDocument = await Formatter.FormatAsync(document, document.Project.Solution.Workspace.Options);

            return(await TextChanges.GetAsync(newDocument, document));
        }
        public static async Task <IEnumerable <LinePositionSpanTextChange> > GetFormattedTextChanges(Document document, OmniSharpOptions omnisharpOptions, ILoggerFactory loggerFactory)
        {
            var newDocument = await FormatDocument(document, omnisharpOptions, loggerFactory);

            return(await TextChanges.GetAsync(newDocument, document));
        }
        public static async Task <IEnumerable <LinePositionSpanTextChange> > GetFormattingChanges(Document document, int start, int end, OmniSharpOptions omnisharpOptions, ILoggerFactory loggerFactory)
        {
            var newDocument = await FormatDocument(document, omnisharpOptions, loggerFactory, TextSpan.FromBounds(start, end));

            return(await TextChanges.GetAsync(newDocument, document));
        }
Example #7
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);
        }
Example #8
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);
        }
Example #9
0
        public static async Task <IEnumerable <LinePositionSpanTextChange> > GetFormattingChanges(Document document, int start, int end)
        {
            var newDocument = await Formatter.FormatAsync(document, TextSpan.FromBounds(start, end), document.Project.Solution.Workspace.Options);

            return(await TextChanges.GetAsync(newDocument, document));
        }
Example #10
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.Lines.GetPosition(new LinePosition(request.Line, request.Column));

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

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