private async ValueTask <DifferenceViewerPreview> CreateNewDifferenceViewerAsync( PreviewWorkspace?leftWorkspace, PreviewWorkspace?rightWorkspace, IProjectionBuffer originalBuffer, IProjectionBuffer changedBuffer, double zoomLevel, CancellationToken cancellationToken) { // IWpfDifferenceViewerFactoryService is a Visual Studio API which is not documented as free-threaded await ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); // leftWorkspace can be null if the change is adding a document. // rightWorkspace can be null if the change is removing a document. // However both leftWorkspace and rightWorkspace can't be null at the same time. Contract.ThrowIfTrue((leftWorkspace == null) && (rightWorkspace == null)); var diffBuffer = _differenceBufferService.CreateDifferenceBuffer( originalBuffer, changedBuffer, new StringDifferenceOptions(), disableEditing: true); var mode = leftWorkspace == null ? DifferenceViewMode.RightViewOnly : rightWorkspace == null ? DifferenceViewMode.LeftViewOnly : DifferenceViewMode.Inline; var diffViewer = await CreateDifferenceViewAsync(diffBuffer, _previewRoleSet, mode, zoomLevel, cancellationToken).ConfigureAwait(true); diffViewer.Closed += (s, e) => { // Workaround Editor bug. The editor has an issue where they sometimes crash when // trying to apply changes to projection buffer. So, when the user actually invokes // a SuggestedAction we may then edit a text buffer, which the editor will then // try to propagate through the projections we have here over that buffer. To ensure // that that doesn't happen, we clear out the projections first so that this crash // won't happen. originalBuffer.DeleteSpans(0, originalBuffer.CurrentSnapshot.SpanCount); changedBuffer.DeleteSpans(0, changedBuffer.CurrentSnapshot.SpanCount); leftWorkspace?.Dispose(); leftWorkspace = null; rightWorkspace?.Dispose(); rightWorkspace = null; }; if (_globalOptions.GetOption(SolutionCrawlerRegistrationService.EnableSolutionCrawler)) { leftWorkspace?.EnableSolutionCrawler(); rightWorkspace?.EnableSolutionCrawler(); } return(new DifferenceViewerPreview(diffViewer)); }
public async Task TestPreviewDiagnostic() { var hostServices = EditorTestCompositions.EditorFeatures.GetHostServices(); var exportProvider = (IMefHostExportProvider)hostServices; var diagnosticService = (IDiagnosticUpdateSource)exportProvider.GetExportedValue <IDiagnosticAnalyzerService>(); RoslynDebug.AssertNotNull(diagnosticService); var globalOptions = exportProvider.GetExportedValue <IGlobalOptionService>(); var taskSource = new TaskCompletionSource <DiagnosticsUpdatedArgs>(); diagnosticService.DiagnosticsUpdated += (s, a) => taskSource.TrySetResult(a); using var previewWorkspace = new PreviewWorkspace(hostServices); var solution = previewWorkspace.CurrentSolution .WithAnalyzerReferences(new[] { DiagnosticExtensions.GetCompilerDiagnosticAnalyzerReference(LanguageNames.CSharp) }) .AddProject("project", "project.dll", LanguageNames.CSharp) .AddDocument("document", "class { }") .Project .Solution; Assert.True(previewWorkspace.TryApplyChanges(solution)); var document = previewWorkspace.CurrentSolution.Projects.First().Documents.Single(); previewWorkspace.OpenDocument(document.Id, (await document.GetTextAsync()).Container); previewWorkspace.EnableSolutionCrawler(); // wait 20 seconds taskSource.Task.Wait(20000); Assert.True(taskSource.Task.IsCompleted); var args = taskSource.Task.Result; Assert.True(args.GetPushDiagnostics(globalOptions, InternalDiagnosticsOptions.NormalDiagnosticMode).Length > 0); }
public async Task TestPreviewDiagnosticTagger() { using var workspace = TestWorkspace.CreateCSharp("class { }", composition: EditorTestCompositions.EditorFeatures); using var previewWorkspace = new PreviewWorkspace(workspace.CurrentSolution); // preview workspace and owner of the solution now share solution and its underlying text buffer var hostDocument = workspace.Projects.First().Documents.First(); previewWorkspace.TryApplyChanges(previewWorkspace.CurrentSolution.WithAnalyzerReferences(new[] { DiagnosticExtensions.GetCompilerDiagnosticAnalyzerReference(LanguageNames.CSharp) })); // enable preview diagnostics previewWorkspace.EnableSolutionCrawler(); var diagnosticsAndErrorsSpans = await SquiggleUtilities.GetDiagnosticsAndErrorSpansAsync <DiagnosticsSquiggleTaggerProvider, IErrorTag>(workspace); const string AnalyzerCount = "Analyzer Count: "; Assert.Equal(AnalyzerCount + 1, AnalyzerCount + diagnosticsAndErrorsSpans.Item1.Length); const string SquigglesCount = "Squiggles Count: "; Assert.Equal(SquigglesCount + 1, SquigglesCount + diagnosticsAndErrorsSpans.Item2.Length); }