public async Task HandleRequestAsync_DocumentNotFound_ClearsDiagnostics() { // Arrange var documentManager = new TestDocumentManager(); var requestInvoker = Mock.Of <LSPRequestInvoker>(MockBehavior.Strict); var diagnosticsProvider = Mock.Of <LSPDiagnosticsTranslator>(MockBehavior.Strict); var documentSynchronizer = Mock.Of <LSPDocumentSynchronizer>(MockBehavior.Strict); var documentDiagnosticsHandler = new DocumentPullDiagnosticsHandler(requestInvoker, documentManager, documentSynchronizer, diagnosticsProvider, LoggerProvider); var diagnosticRequest = new VSInternalDocumentDiagnosticsParams() { TextDocument = new TextDocumentIdentifier() { Uri = Uri }, PreviousResultId = "4" }; // Act var result = await documentDiagnosticsHandler.HandleRequestAsync(diagnosticRequest, new ClientCapabilities(), CancellationToken.None).ConfigureAwait(false); // Assert var report = Assert.Single(result); Assert.Null(report.Diagnostics); Assert.Null(report.ResultId); }
public Task <VSInternalDiagnosticReport[]?> GetDocumentPullDiagnosticsAsync(VSInternalDocumentDiagnosticsParams diagnosticsParams, CancellationToken cancellationToken) { Contract.ThrowIfNull(_clientCapabilities, $"{nameof(InitializeAsync)} has not been called."); return(RequestDispatcher.ExecuteRequestAsync <VSInternalDocumentDiagnosticsParams, VSInternalDiagnosticReport[]?>( Queue, VSInternalMethods.DocumentPullDiagnosticName, diagnosticsParams, _clientCapabilities, ClientName, cancellationToken)); }
public async Task HandleRequestAsync_RemapsDiagnosticRange() { // Arrange var called = false; var documentManager = CreateDocumentManager(); var requestInvoker = GetRequestInvoker <VSInternalDocumentDiagnosticsParams, VSInternalDiagnosticReport[]>( s_roslynDiagnosticResponse, (textBuffer, method, diagnosticParams, ct) => { Assert.Equal(VSInternalMethods.DocumentPullDiagnosticName, method); called = true; }); var diagnosticsProvider = GetDiagnosticsProvider(s_validDiagnostic_UnknownName_MappedRange, s_validDiagnostic_InvalidExpression_MappedRange); var documentSynchronizer = CreateDocumentSynchronizer(); var documentDiagnosticsHandler = new DocumentPullDiagnosticsHandler(requestInvoker, documentManager, documentSynchronizer, diagnosticsProvider, LoggerProvider); var diagnosticRequest = new VSInternalDocumentDiagnosticsParams() { TextDocument = new TextDocumentIdentifier() { Uri = Uri }, PreviousResultId = "4" }; // Act var result = await documentDiagnosticsHandler.HandleRequestAsync(diagnosticRequest, new ClientCapabilities(), CancellationToken.None).ConfigureAwait(false); // Assert Assert.True(called); var diagnosticReport = Assert.Single(result); Assert.Equal(s_roslynDiagnosticResponse.First().ResultId, diagnosticReport.ResultId); Assert.Collection(diagnosticReport.Diagnostics, d => { Assert.Equal(s_validDiagnostic_UnknownName.Code, d.Code); Assert.Equal(s_validDiagnostic_UnknownName_MappedRange, d.Range); }, d => { Assert.Equal(s_validDiagnostic_InvalidExpression.Code, d.Code); Assert.Equal(s_validDiagnostic_InvalidExpression_MappedRange, d.Range); }); }
public async Task HandleRequestAsync_DocumentSynchronizationFails_ReturnsNullDiagnostic() { // Arrange var called = false; var documentManager = CreateDocumentManager(); var requestInvoker = GetRequestInvoker <VSInternalDocumentDiagnosticsParams, VSInternalDiagnosticReport[]>( s_roslynDiagnosticResponse, (textBuffer, method, diagnosticParams, ct) => { Assert.Equal(VSInternalMethods.DocumentPullDiagnosticName, method); called = true; }); var diagnosticsProvider = GetDiagnosticsProvider(s_validDiagnostic_UnknownName_MappedRange, s_validDiagnostic_InvalidExpression_MappedRange); var documentSynchronizer = new Mock <LSPDocumentSynchronizer>(MockBehavior.Strict); documentSynchronizer .Setup(d => d.TrySynchronizeVirtualDocumentAsync(It.IsAny <int>(), It.IsAny <CSharpVirtualDocumentSnapshot>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(false)); var documentDiagnosticsHandler = new DocumentPullDiagnosticsHandler(requestInvoker, documentManager, documentSynchronizer.Object, diagnosticsProvider, LoggerProvider); var diagnosticRequest = new VSInternalDocumentDiagnosticsParams() { TextDocument = new TextDocumentIdentifier() { Uri = Uri }, PreviousResultId = "4" }; // Act var result = await documentDiagnosticsHandler.HandleRequestAsync(diagnosticRequest, new ClientCapabilities(), CancellationToken.None).ConfigureAwait(false); // Assert Assert.False(called); var diagnosticReport = Assert.Single(result); Assert.Equal(diagnosticRequest.PreviousResultId, diagnosticReport.ResultId); Assert.Null(diagnosticReport.Diagnostics); }
public async Task TestRoslynTypeScriptHandlerInvoked() { var workspaceXml = @$ "<Workspace> <Project Language=" "TypeScript" " CommonReferences=" "true" " AssemblyName=" "TypeScriptProj" "> <Document FilePath=" "C:\T.ts" "></Document> </Project> </Workspace>"; using var testLspServer = await CreateTsTestLspServerAsync(workspaceXml); var document = testLspServer.GetCurrentSolution().Projects.Single().Documents.Single(); var documentPullRequest = new VSInternalDocumentDiagnosticsParams { TextDocument = CreateTextDocumentIdentifier(document.GetURI(), document.Project.Id) }; var response = await testLspServer.ExecuteRequestAsync <VSInternalDocumentDiagnosticsParams, VSInternalDiagnosticReport[]>(VSInternalMethods.DocumentPullDiagnosticName, documentPullRequest, CancellationToken.None); Assert.Empty(response); }
public async Task HandleRequestAsync_VersionMismatch_DiscardsLocation() { // Arrange var called = false; var documentManager = CreateDocumentManager(hostDocumentVersion: 1); var requestInvoker = GetRequestInvoker <VSInternalDocumentDiagnosticsParams, VSInternalDiagnosticReport[]>( s_roslynDiagnosticResponse, (textBuffer, method, diagnosticParams, ct) => { Assert.Equal(VSInternalMethods.DocumentPullDiagnosticName, method); called = true; }); // Note the HostDocumentVersion provided by the DiagnosticsProvider = 0, // which is different from document version (1) from the DocumentManager var diagnosticsProvider = GetDiagnosticsProvider(s_validDiagnostic_UnknownName_MappedRange, s_validDiagnostic_InvalidExpression_MappedRange); var documentSynchronizer = CreateDocumentSynchronizer(); var documentDiagnosticsHandler = new DocumentPullDiagnosticsHandler(requestInvoker, documentManager, documentSynchronizer, diagnosticsProvider, LoggerProvider); var diagnosticRequest = new VSInternalDocumentDiagnosticsParams() { TextDocument = new TextDocumentIdentifier() { Uri = Uri }, PreviousResultId = "4" }; // Act var result = await documentDiagnosticsHandler.HandleRequestAsync(diagnosticRequest, new ClientCapabilities(), CancellationToken.None).ConfigureAwait(false); // Assert Assert.True(called); var returnedReport = Assert.Single(result); Assert.Equal(s_roslynDiagnosticResponse.First().ResultId, returnedReport.ResultId); Assert.Null(returnedReport.Diagnostics); }
public async Task HandleRequestAsync_NoDiagnosticsAfterFiltering_ReturnsNullDiagnostic() { // Arrange var called = false; var documentManager = CreateDocumentManager(); var filteredDiagnostic = new Diagnostic() { Range = new Range() { Start = new Position(159, 19), End = new Position(159, 23) }, Code = "RemoveUnnecessaryImportsFixable", Severity = DiagnosticSeverity.Warning }; var filteredDiagnostic_mappedRange = new Range() { Start = new Position(49, 19), End = new Position(49, 23) }; var diagnosticReport = new VSInternalDiagnosticReport() { ResultId = "6", Diagnostics = new Diagnostic[] { filteredDiagnostic } }; var requestInvoker = GetRequestInvoker <VSInternalDocumentDiagnosticsParams, VSInternalDiagnosticReport[]>( new[] { diagnosticReport }, (textBuffer, method, diagnosticParams, ct) => { Assert.Equal(VSInternalMethods.DocumentPullDiagnosticName, method); called = true; }); var diagnosticsProvider = GetDiagnosticsProvider(filteredDiagnostic_mappedRange); var documentSynchronizer = CreateDocumentSynchronizer(); var documentDiagnosticsHandler = new DocumentPullDiagnosticsHandler(requestInvoker, documentManager, documentSynchronizer, diagnosticsProvider, LoggerProvider); var diagnosticRequest = new VSInternalDocumentDiagnosticsParams() { TextDocument = new TextDocumentIdentifier() { Uri = Uri }, PreviousResultId = "4" }; // Act var result = await documentDiagnosticsHandler.HandleRequestAsync(diagnosticRequest, new ClientCapabilities(), CancellationToken.None).ConfigureAwait(false); // Assert Assert.True(called); var returnedReport = Assert.Single(result); Assert.Equal(diagnosticReport.ResultId, returnedReport.ResultId); Assert.Empty(returnedReport.Diagnostics); }
public async Task HandleRequestAsync_RemapFailsButErrorDiagnosticIsShown() { // Arrange var called = false; var documentManager = CreateDocumentManager(); var unmappableDiagnostic_errorSeverity = new Diagnostic() { Range = new Range() { Start = new Position(149, 19), End = new Position(149, 23) }, Code = "CS0103", Severity = DiagnosticSeverity.Error }; var unmappableDiagnostic_warningSeverity = new Diagnostic() { Range = new Range() { Start = new Position(159, 19), End = new Position(159, 23) }, Code = "IDE003", Severity = DiagnosticSeverity.Warning }; var diagnosticReport = new VSInternalDiagnosticReport() { ResultId = "6", Diagnostics = new Diagnostic[] { unmappableDiagnostic_errorSeverity, unmappableDiagnostic_warningSeverity } }; var requestInvoker = GetRequestInvoker <VSInternalDocumentDiagnosticsParams, VSInternalDiagnosticReport[]>( new[] { diagnosticReport }, (textBuffer, method, diagnosticParams, ct) => { Assert.Equal(VSInternalMethods.DocumentPullDiagnosticName, method); called = true; }); var undefinedRange = new Range() { Start = new Position(-1, -1), End = new Position(-1, -1) }; var diagnosticsProvider = GetDiagnosticsProvider(undefinedRange, undefinedRange); var documentSynchronizer = CreateDocumentSynchronizer(); var documentDiagnosticsHandler = new DocumentPullDiagnosticsHandler(requestInvoker, documentManager, documentSynchronizer, diagnosticsProvider, LoggerProvider); var diagnosticRequest = new VSInternalDocumentDiagnosticsParams() { TextDocument = new TextDocumentIdentifier() { Uri = Uri }, PreviousResultId = "4" }; // Act var result = await documentDiagnosticsHandler.HandleRequestAsync(diagnosticRequest, new ClientCapabilities(), CancellationToken.None).ConfigureAwait(false); // Assert Assert.True(called); var diagnosticReportResult = Assert.Single(result); Assert.Equal(diagnosticReport.ResultId, diagnosticReportResult.ResultId); var returnedDiagnostic = Assert.Single(diagnosticReportResult.Diagnostics); Assert.Equal(unmappableDiagnostic_errorSeverity.Code, returnedDiagnostic.Code); Assert.True(returnedDiagnostic.Range.IsUndefined()); }
// Internal for testing public async Task <IReadOnlyList <VSInternalDiagnosticReport> > HandleRequestAsync(VSInternalDocumentDiagnosticsParams request, ClientCapabilities clientCapabilities, CancellationToken cancellationToken) { if (request is null) { throw new ArgumentNullException(nameof(request)); } if (clientCapabilities is null) { throw new ArgumentNullException(nameof(clientCapabilities)); } _logger.LogInformation($"Starting request for {request.TextDocument.Uri}."); if (!_documentManager.TryGetDocument(request.TextDocument.Uri, out var documentSnapshot)) { _logger.LogInformation($"Document {request.TextDocument.Uri} closed or deleted, clearing diagnostics."); var clearedDiagnosticReport = new VSInternalDiagnosticReport[] { new VSInternalDiagnosticReport() { ResultId = null, Diagnostics = null } }; return(clearedDiagnosticReport); } if (!documentSnapshot.TryGetVirtualDocument <CSharpVirtualDocumentSnapshot>(out var csharpDoc)) { _logger.LogWarning($"Failed to find virtual C# document for {request.TextDocument.Uri}."); return(null); } var synchronized = await _documentSynchronizer.TrySynchronizeVirtualDocumentAsync( documentSnapshot.Version, csharpDoc, cancellationToken).ConfigureAwait(false); if (!synchronized) { _logger.LogInformation($"Failed to synchronize document {csharpDoc.Uri}."); // Could not synchronize, report nothing changed return(new VSInternalDiagnosticReport[] { new VSInternalDiagnosticReport() { ResultId = request.PreviousResultId, Diagnostics = null } }); } var referenceParams = new VSInternalDocumentDiagnosticsParams() { TextDocument = new TextDocumentIdentifier() { Uri = csharpDoc.Uri }, PreviousResultId = request.PreviousResultId }; _logger.LogInformation($"Requesting diagnostics for {csharpDoc.Uri} with previous result Id of {request.PreviousResultId}."); var textBuffer = csharpDoc.Snapshot.TextBuffer; var requests = _requestInvoker.ReinvokeRequestOnMultipleServersAsync <VSInternalDocumentDiagnosticsParams, VSInternalDiagnosticReport[]>( textBuffer, VSInternalMethods.DocumentPullDiagnosticName, referenceParams, cancellationToken).ConfigureAwait(false); var resultsFromAllLanguageServers = new List <VSInternalDiagnosticReport>(); await foreach (var response in requests) { if (response.Response is not null) { resultsFromAllLanguageServers.AddRange(response.Response); } } _logger.LogInformation($"Received {resultsFromAllLanguageServers.Count} diagnostic reports."); var processedResults = await RemapDocumentDiagnosticsAsync( resultsFromAllLanguageServers, request.TextDocument.Uri, cancellationToken).ConfigureAwait(false); // | ---------------------------------------------------------------------------------- | // | LSP Platform Expected Response Semantics | // | ---------------------------------------------------------------------------------- | // | DiagnosticReport.Diagnostics | DiagnosticReport.ResultId | Meaning | // | -------------------------------- | ------------------------- | ------------------- | // | `null` | `null` | document gone | // | `null` | valid | nothing changed | // | valid (non-null including empty) | valid | diagnostics changed | // | ---------------------------------------------------------------------------------- | return(processedResults); }
public Task <IReadOnlyList <VSInternalDiagnosticReport> > DocumentPullDiagnosticsAsync(VSInternalDocumentDiagnosticsParams documentDiagnosticsParams, CancellationToken cancellationToken) { if (documentDiagnosticsParams is null) { throw new ArgumentNullException(nameof(documentDiagnosticsParams)); } return(ExecuteRequestAsync <VSInternalDocumentDiagnosticsParams, IReadOnlyList <VSInternalDiagnosticReport> >(VSInternalMethods.DocumentPullDiagnosticName, documentDiagnosticsParams, ClientCapabilities, cancellationToken)); }