private async Task <RazorDocumentRangeFormattingResponse> FormatAsync(RazorDocumentRangeFormattingParams @params) { if (@params.Kind != RazorLanguageKind.CSharp) { throw new NotImplementedException($"{@params.Kind} formatting is not yet supported."); } var options = @params.Options; var workspace = new AdhocWorkspace(); var cSharpOptions = workspace.Options .WithChangedOption(FormattingOptions.TabSize, LanguageNames.CSharp, (int)options.TabSize) .WithChangedOption(FormattingOptions.UseTabs, LanguageNames.CSharp, !options.InsertSpaces); var codeDocument = _documents[@params.HostDocumentFilePath]; var csharpDocument = codeDocument.GetCSharpDocument(); var syntaxTree = CSharpSyntaxTree.ParseText(csharpDocument.GeneratedCode); var sourceText = SourceText.From(csharpDocument.GeneratedCode); var root = await syntaxTree.GetRootAsync(); var spanToFormat = @params.ProjectedRange.AsTextSpan(sourceText); var changes = Formatter.GetFormattedTextChanges(root, spanToFormat, workspace, options: cSharpOptions); var response = new RazorDocumentRangeFormattingResponse() { Edits = changes.Select(c => c.AsTextEdit(sourceText)).ToArray() }; return(response); }
public async Task <TextEdit[]> FormatAsync( FormattingContext context, Range rangeToFormat, CancellationToken cancellationToken) { if (context is null) { throw new ArgumentNullException(nameof(context)); } if (rangeToFormat is null) { throw new ArgumentNullException(nameof(rangeToFormat)); } var @params = new RazorDocumentRangeFormattingParams() { Kind = RazorLanguageKind.Html, ProjectedRange = rangeToFormat, HostDocumentFilePath = _filePathNormalizer.Normalize(context.Uri.GetAbsoluteOrUNCPath()), Options = context.Options }; var response = _server.SendRequest(LanguageServerConstants.RazorRangeFormattingEndpoint, @params); var result = await response.Returning <RazorDocumentRangeFormattingResponse>(cancellationToken); return(result.Edits); }
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); }
public async Task <TextEdit[]> FormatAsync( RazorCodeDocument codeDocument, Range range, Uri uri, FormattingOptions options) { if (!_documentMappingService.TryMapToProjectedDocumentRange(codeDocument, range, out var projectedRange)) { return(Array.Empty <TextEdit>()); } var @params = new RazorDocumentRangeFormattingParams() { Kind = RazorLanguageKind.CSharp, ProjectedRange = projectedRange, HostDocumentFilePath = _filePathNormalizer.Normalize(uri.GetAbsoluteOrUNCPath()), Options = options }; var result = await _server.Client.SendRequest <RazorDocumentRangeFormattingParams, RazorDocumentRangeFormattingResponse>( LanguageServerConstants.RazorRangeFormattingEndpoint, @params); var mappedEdits = MapEditsToHostDocument(codeDocument, result.Edits); return(mappedEdits); }
private async Task <TextEdit[]> FormatOnClientAsync( FormattingContext context, Range projectedRange, CancellationToken cancellationToken) { var @params = new RazorDocumentRangeFormattingParams() { Kind = RazorLanguageKind.CSharp, ProjectedRange = projectedRange, HostDocumentFilePath = _filePathNormalizer.Normalize(context.Uri.GetAbsoluteOrUNCPath()), Options = context.Options }; var response = _server.SendRequest(LanguageServerConstants.RazorRangeFormattingEndpoint, @params); var result = await response.Returning <RazorDocumentRangeFormattingResponse>(cancellationToken); return(result.Edits); }
public async Task <TextEdit[]> FormatAsync( RazorCodeDocument codeDocument, Range range, Uri uri, LSPFormattingOptions options) { var @params = new RazorDocumentRangeFormattingParams() { Kind = RazorLanguageKind.Html, ProjectedRange = range, HostDocumentFilePath = _filePathNormalizer.Normalize(uri.GetAbsoluteOrUNCPath()), Options = options }; var result = await _server.Client.SendRequest <RazorDocumentRangeFormattingParams, RazorDocumentRangeFormattingResponse>( LanguageServerConstants.RazorRangeFormattingEndpoint, @params); return(result.Edits); }
private RazorDocumentRangeFormattingResponse 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 RazorDocumentRangeFormattingResponse(); 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 if (@params.Kind == RazorLanguageKind.Html) { response.Edits = Array.Empty <TextEdit>(); var codeDocument = _documents[@params.HostDocumentFilePath]; var generatedHtml = codeDocument.GetHtmlDocument().GeneratedHtml; generatedHtml = generatedHtml.Replace("\r", "", StringComparison.Ordinal).Replace("\n", "\r\n", StringComparison.Ordinal); // Get formatted baseline file var baselineInputFileName = Path.ChangeExtension(_baselineFileName, ".input.html"); var baselineOutputFileName = Path.ChangeExtension(_baselineFileName, ".output.html"); var baselineInputFile = TestFile.Create(baselineInputFileName, GetType().GetTypeInfo().Assembly); var baselineOutputFile = TestFile.Create(baselineOutputFileName, GetType().GetTypeInfo().Assembly); if (GenerateBaselines) { if (baselineInputFile.Exists()) { // If it already exists, we only want to update if the input is different. var inputContent = baselineInputFile.ReadAllText(); if (string.Equals(inputContent, generatedHtml, StringComparison.Ordinal)) { return(response); } } var baselineInputFilePath = Path.Combine(_projectPath, baselineInputFileName); File.WriteAllText(baselineInputFilePath, generatedHtml); var baselineOutputFilePath = Path.Combine(_projectPath, baselineOutputFileName); File.WriteAllText(baselineOutputFilePath, generatedHtml); return(response); } if (!baselineInputFile.Exists()) { throw new XunitException($"The resource {baselineInputFileName} was not found."); } if (!baselineOutputFile.Exists()) { throw new XunitException($"The resource {baselineOutputFileName} was not found."); } var baselineInputHtml = baselineInputFile.ReadAllText(); if (!string.Equals(baselineInputHtml, generatedHtml, StringComparison.Ordinal)) { throw new XunitException($"The baseline for {_baselineFileName} is out of date."); } var baselineOutputHtml = baselineOutputFile.ReadAllText(); var baselineInputText = SourceText.From(baselineInputHtml); var baselineOutputText = SourceText.From(baselineOutputHtml); var changes = SourceTextDiffer.GetMinimalTextChanges(baselineInputText, baselineOutputText, lineDiffOnly: false); var edits = changes.Select(c => c.AsTextEdit(baselineInputText)).ToArray(); response.Edits = edits; } return(response); }
private RazorDocumentRangeFormattingResponse 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 RazorDocumentRangeFormattingResponse(); 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 if (@params.Kind == RazorLanguageKind.Html) { response.Edits = Array.Empty <TextEdit>(); var codeDocument = _documents[@params.HostDocumentFilePath]; 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>(); 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.HostDocumentFilePath}"); 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} }}, ""SpanToFormat"": {{ ""start"": {@params.ProjectedRange.AsTextSpan(generatedHtmlSource).Start}, ""length"": {@params.ProjectedRange.AsTextSpan(generatedHtmlSource).Length}, }}, ""Uri"": ""file:///{@params.HostDocumentFilePath}"", ""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); }