private RazorDocumentFormattingResponse Format(RazorDocumentRangeFormattingParams @params)
        {
            if (@params.Kind == RazorLanguageKind.Razor)
            {
                throw new InvalidOperationException("We shouldn't be asked to format Razor language kind.");
            }

            var options  = @params.Options;
            var response = new RazorDocumentFormattingResponse();

            if (@params.Kind == RazorLanguageKind.CSharp)
            {
                var codeDocument     = _documents[@params.HostDocumentFilePath];
                var csharpSourceText = codeDocument.GetCSharpSourceText();
                var csharpDocument   = GetCSharpDocument(codeDocument, @params.Options);
                if (!csharpDocument.TryGetSyntaxRoot(out var root))
                {
                    throw new InvalidOperationException("Couldn't get syntax root.");
                }
                var spanToFormat = @params.ProjectedRange.AsTextSpan(csharpSourceText);

                var changes = Formatter.GetFormattedTextChanges(root, spanToFormat, csharpDocument.Project.Solution.Workspace);

                response.Edits = changes.Select(c => c.AsTextEdit(csharpSourceText)).ToArray();
            }
            else
            {
                throw new InvalidOperationException($"We shouldn't be asked to format {@params.Kind} language kind.");
            }

            return(response);
        }
Example #2
0
        private RazorDocumentFormattingResponse Format(DocumentOnTypeFormattingParams @params)
        {
            var response = new RazorDocumentFormattingResponse();

            response.Edits = Array.Empty <TextEdit>();

            // TODO: Update WebTools dependency and call via reflection

            return(response);
        }
        private RazorDocumentFormattingResponse Format(DocumentFormattingParams @params)
        {
            var options  = @params.Options;
            var response = new RazorDocumentFormattingResponse();

            response.Edits = Array.Empty <TextEdit>();

            var codeDocument  = _documents[@params.TextDocument.Uri.GetAbsoluteOrUNCPath()];
            var generatedHtml = codeDocument.GetHtmlDocument().GeneratedHtml;

            generatedHtml = generatedHtml.Replace("\r", "", StringComparison.Ordinal).Replace("\n", "\r\n", StringComparison.Ordinal);
            var generatedHtmlSource = SourceText.From(generatedHtml, Encoding.UTF8);

            var editHandlerAssembly = Assembly.Load("Microsoft.WebTools.Languages.LanguageServer.Server, Version=16.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
            var editHandlerType     = editHandlerAssembly.GetType("Microsoft.WebTools.Languages.LanguageServer.Server.Html.OperationHandlers.ApplyFormatEditsHandler", throwOnError: true);
            var bufferManagerType   = editHandlerAssembly.GetType("Microsoft.WebTools.Languages.LanguageServer.Server.Shared.Buffer.BufferManager", throwOnError: true);

            var exportProvider     = EditorTestCompositions.Editor.ExportProviderFactory.CreateExportProvider();
            var contentTypeService = exportProvider.GetExportedValue <IContentTypeRegistryService>();

            if (!contentTypeService.ContentTypes.Any(t => t.TypeName == HtmlContentTypeDefinition.HtmlContentType))
            {
                contentTypeService.AddContentType(HtmlContentTypeDefinition.HtmlContentType, new[] { StandardContentTypeNames.Text });
            }

            var textBufferFactoryService          = exportProvider.GetExportedValue <ITextBufferFactoryService>();
            var textBufferListeners               = Array.Empty <Lazy <IWebTextBufferListener, IOrderedComponentContentTypes> >();
            var bufferManager                     = Activator.CreateInstance(bufferManagerType, new object[] { contentTypeService, textBufferFactoryService, textBufferListeners });
            var joinableTaskFactoryThreadSwitcher = typeof(IdAttribute).Assembly.GetType("Microsoft.WebTools.Shared.Threading.JoinableTaskFactoryThreadSwitcher", throwOnError: true);
            var threadSwitcher                    = (IThreadSwitcher)Activator.CreateInstance(joinableTaskFactoryThreadSwitcher, new object[] { new JoinableTaskContext().Factory });
            var applyFormatEditsHandler           = Activator.CreateInstance(editHandlerType, new object[] { bufferManager, threadSwitcher, textBufferFactoryService });

            // Make sure the buffer manager knows about the source document
            var documentUri            = DocumentUri.From($"file:///{@params.TextDocument.Uri}");
            var contentTypeName        = HtmlContentTypeDefinition.HtmlContentType;
            var initialContent         = generatedHtml;
            var snapshotVersionFromLSP = 0;

            Assert.IsAssignableFrom <ITextSnapshot>(bufferManager.GetType().GetMethod("CreateBuffer").Invoke(bufferManager, new object[] { documentUri, contentTypeName, initialContent, snapshotVersionFromLSP }));

            var requestType           = editHandlerAssembly.GetType("Microsoft.WebTools.Languages.LanguageServer.Server.ContainedLanguage.ApplyFormatEditsParamForOmniSharp", throwOnError: true);
            var serializedValue       = $@"{{
    ""Options"": {{
        ""UseSpaces"": {(@params.Options.InsertSpaces ? "true" : "false")},
        ""TabSize"": {@params.Options.TabSize},
        ""IndentSize"": {@params.Options.TabSize}
    }},
    ""Uri"": ""file:///{@params.TextDocument.Uri}"",
    ""GeneratedChanges"": [
    ]
}}
";
            var request               = JsonConvert.DeserializeObject(serializedValue, requestType);
            var resultTask            = (Task)applyFormatEditsHandler.GetType().GetRuntimeMethod("Handle", new Type[] { requestType, typeof(CancellationToken) }).Invoke(applyFormatEditsHandler, new object[] { request, CancellationToken.None });
            var result                = resultTask.GetType().GetProperty(nameof(Task <int> .Result)).GetValue(resultTask);
            var rawTextChanges        = result.GetType().GetProperty("TextChanges").GetValue(result);
            var serializedTextChanges = JsonConvert.SerializeObject(rawTextChanges, Newtonsoft.Json.Formatting.Indented);
            var textChanges           = JsonConvert.DeserializeObject <HtmlFormatterTextEdit[]>(serializedTextChanges);

            response.Edits = textChanges.Select(change => change.AsTextEdit(SourceText.From(generatedHtml))).ToArray();

            return(response);
        }