internal static IList<ITagSpan<IErrorTag>> GetErrorsFromUpdateSource(TestWorkspace workspace, TestHostDocument document, DiagnosticsUpdatedArgs updateArgs)
        {
            var source = new TestDiagnosticUpdateSource();

            var diagnosticWaiter = new DiagnosticServiceWaiter();
            var diagnosticListeners = SpecializedCollections.SingletonEnumerable(new Lazy<IAsynchronousOperationListener, FeatureMetadata>(
                () => diagnosticWaiter, new FeatureMetadata(new Dictionary<string, object>() { { "FeatureName", FeatureAttribute.DiagnosticService } })));

            var optionsService = workspace.Services.GetService<IOptionService>();
            var diagnosticService = new DiagnosticService(SpecializedCollections.SingletonEnumerable<IDiagnosticUpdateSource>(source), diagnosticListeners);

            var squiggleWaiter = new ErrorSquiggleWaiter();
            var foregroundService = new TestForegroundNotificationService();

            var buffer = document.GetTextBuffer();
            var taggerSource = new DiagnosticsSquiggleTaggerProvider.TagSource(buffer, foregroundService, diagnosticService, optionsService, squiggleWaiter);

            source.RaiseDiagnosticsUpdated(updateArgs);

            diagnosticWaiter.CreateWaitTask().PumpingWait();
            squiggleWaiter.CreateWaitTask().PumpingWait();

            var snapshot = buffer.CurrentSnapshot;
            var intervalTree = taggerSource.GetTagIntervalTreeForBuffer(buffer);
            var spans = intervalTree.GetIntersectingSpans(new SnapshotSpan(snapshot, 0, snapshot.Length));

            taggerSource.TestOnly_Dispose();

            return spans;
        }
        internal static IList <ITagSpan <IErrorTag> > GetErrorsFromUpdateSource(TestWorkspace workspace, TestHostDocument document, DiagnosticsUpdatedArgs updateArgs)
        {
            var source = new TestDiagnosticUpdateSource();

            var diagnosticWaiter    = new DiagnosticServiceWaiter();
            var diagnosticListeners = SpecializedCollections.SingletonEnumerable(new Lazy <IAsynchronousOperationListener, FeatureMetadata>(
                                                                                     () => diagnosticWaiter, new FeatureMetadata(new Dictionary <string, object>()
            {
                { "FeatureName", FeatureAttribute.DiagnosticService }
            })));

            var optionsService    = workspace.Services.GetService <IOptionService>();
            var diagnosticService = new DiagnosticService(SpecializedCollections.SingletonEnumerable <IDiagnosticUpdateSource>(source), diagnosticListeners);

            var squiggleWaiter    = new ErrorSquiggleWaiter();
            var foregroundService = new TestForegroundNotificationService();

            var buffer       = document.GetTextBuffer();
            var taggerSource = new DiagnosticsSquiggleTaggerProvider.TagSource(buffer, foregroundService, diagnosticService, optionsService, squiggleWaiter);

            source.RaiseDiagnosticsUpdated(updateArgs);

            diagnosticWaiter.CreateWaitTask().PumpingWait();
            squiggleWaiter.CreateWaitTask().PumpingWait();

            var snapshot     = buffer.CurrentSnapshot;
            var intervalTree = taggerSource.GetTagIntervalTreeForBuffer(buffer);
            var spans        = intervalTree.GetIntersectingSpans(new SnapshotSpan(snapshot, 0, snapshot.Length));

            taggerSource.TestOnly_Dispose();

            return(spans);
        }
        protected static IEnumerable <ITagSpan <IErrorTag> > GetErrorSpans(TestWorkspace workspace, ImmutableDictionary <string, ImmutableArray <DiagnosticAnalyzer> > analyzerMap = null)
        {
            var registrationService = workspace.Services.GetService <ISolutionCrawlerRegistrationService>();

            registrationService.Register(workspace);

            var diagnosticWaiter    = new DiagnosticServiceWaiter();
            var diagnosticListeners = SpecializedCollections.SingletonEnumerable(new Lazy <IAsynchronousOperationListener, FeatureMetadata>(
                                                                                     () => diagnosticWaiter, new FeatureMetadata(new Dictionary <string, object>()
            {
                { "FeatureName", FeatureAttribute.DiagnosticService }
            })));

            var optionsService = workspace.Services.GetService <IOptionService>();

            DiagnosticAnalyzerService analyzerService = null;

            if (analyzerMap == null || analyzerMap.Count == 0)
            {
                var compilerAnalyzersMap = DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap();
                analyzerService = new TestDiagnosticAnalyzerService(compilerAnalyzersMap);
            }
            else
            {
                analyzerService = new TestDiagnosticAnalyzerService(analyzerMap);
            }

            var diagnosticService = new DiagnosticService(SpecializedCollections.SingletonEnumerable <IDiagnosticUpdateSource>(analyzerService), diagnosticListeners);

            var document = workspace.Documents.First();
            var buffer   = document.GetTextBuffer();

            var squiggleWaiter    = new ErrorSquiggleWaiter();
            var foregroundService = new TestForegroundNotificationService();
            var taggerSource      = new DiagnosticsSquiggleTaggerProvider.TagSource(buffer, foregroundService, diagnosticService, optionsService, squiggleWaiter);

            var service = workspace.Services.GetService <ISolutionCrawlerRegistrationService>() as SolutionCrawlerRegistrationService;

            service.WaitUntilCompletion_ForTestingPurposesOnly(workspace, ImmutableArray.Create(analyzerService.CreateIncrementalAnalyzer(workspace)));

            diagnosticWaiter.CreateWaitTask().PumpingWait();
            squiggleWaiter.CreateWaitTask().PumpingWait();

            var snapshot     = buffer.CurrentSnapshot;
            var intervalTree = taggerSource.GetTagIntervalTreeForBuffer(buffer);
            var spans        = intervalTree.GetIntersectingSpans(new SnapshotSpan(snapshot, 0, snapshot.Length)).ToImmutableArray();

            taggerSource.TestOnly_Dispose();

            registrationService.Unregister(workspace);

            return(spans);
        }
        protected static IEnumerable<ITagSpan<IErrorTag>> GetErrorSpans(TestWorkspace workspace, ImmutableDictionary<string, ImmutableArray<DiagnosticAnalyzer>> analyzerMap = null)
        {
            var registrationService = workspace.Services.GetService<ISolutionCrawlerRegistrationService>();
            registrationService.Register(workspace);

            var diagnosticWaiter = new DiagnosticServiceWaiter();
            var diagnosticListeners = SpecializedCollections.SingletonEnumerable(new Lazy<IAsynchronousOperationListener, FeatureMetadata>(
                () => diagnosticWaiter, new FeatureMetadata(new Dictionary<string, object>() { { "FeatureName", FeatureAttribute.DiagnosticService } })));

            var optionsService = workspace.Services.GetService<IOptionService>();

            DiagnosticAnalyzerService analyzerService = null;
            if (analyzerMap == null || analyzerMap.Count == 0)
            {
                var compilerAnalyzersMap = DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap();
                analyzerService = new TestDiagnosticAnalyzerService(compilerAnalyzersMap);
            }
            else
            {
                analyzerService = new TestDiagnosticAnalyzerService(analyzerMap);
            }

            var diagnosticService = new DiagnosticService(SpecializedCollections.SingletonEnumerable<IDiagnosticUpdateSource>(analyzerService), diagnosticListeners);

            var document = workspace.Documents.First();
            var buffer = document.GetTextBuffer();

            var squiggleWaiter = new ErrorSquiggleWaiter();
            var foregroundService = new TestForegroundNotificationService();
            var taggerSource = new DiagnosticsSquiggleTaggerProvider.TagSource(buffer, foregroundService, diagnosticService, optionsService, squiggleWaiter);

            var service = workspace.Services.GetService<ISolutionCrawlerRegistrationService>() as SolutionCrawlerRegistrationService;
            service.WaitUntilCompletion_ForTestingPurposesOnly(workspace, ImmutableArray.Create(analyzerService.CreateIncrementalAnalyzer(workspace)));

            diagnosticWaiter.CreateWaitTask().PumpingWait();
            squiggleWaiter.CreateWaitTask().PumpingWait();

            var snapshot = buffer.CurrentSnapshot;
            var intervalTree = taggerSource.GetTagIntervalTreeForBuffer(buffer);
            var spans = intervalTree.GetIntersectingSpans(new SnapshotSpan(snapshot, 0, snapshot.Length)).ToImmutableArray();

            taggerSource.TestOnly_Dispose();

            registrationService.Unregister(workspace);

            return spans;
        }
        public void Test_TagSourceDiffer()
        {
            using (var workspace = CSharpWorkspaceFactory.CreateWorkspaceFromFiles(new string[] { "class A { }", "class E { }" }, CSharpParseOptions.Default))
            {
                var registrationService = workspace.Services.GetService <ISolutionCrawlerRegistrationService>();
                registrationService.Register(workspace);

                var diagnosticWaiter = new DiagnosticServiceWaiter();
                var squiggleWaiter   = new ErrorSquiggleWaiter();

                Analyzer analyzer;
                DiagnosticAnalyzerService analyzerService;
                DiagnosticsSquiggleTaggerProvider.TagSource taggerSource;
                GetTagSource(workspace, diagnosticWaiter, squiggleWaiter, out analyzer, out analyzerService, out taggerSource);

                taggerSource.TagsChangedForBuffer += (o, arg) =>
                {
                    Assert.True(arg.Spans.First().Span.Contains(new Span(0, 1)));
                };

                var service = workspace.Services.GetService <ISolutionCrawlerRegistrationService>() as SolutionCrawlerRegistrationService;
                var incrementalAnalyzers = ImmutableArray.Create(analyzerService.CreateIncrementalAnalyzer(workspace));

                // test first update
                service.WaitUntilCompletion_ForTestingPurposesOnly(workspace, incrementalAnalyzers);

                diagnosticWaiter.CreateWaitTask().PumpingWait();
                squiggleWaiter.CreateWaitTask().PumpingWait();

                // test second update
                analyzer.ChangeSeverity();

                var document = workspace.CurrentSolution.GetDocument(workspace.Documents.First().Id);
                var text     = document.GetTextAsync().Result;
                workspace.TryApplyChanges(document.WithText(text.WithChanges(new TextChange(new TextSpan(text.Length - 1, 1), string.Empty))).Project.Solution);

                service.WaitUntilCompletion_ForTestingPurposesOnly(workspace, incrementalAnalyzers);

                diagnosticWaiter.CreateWaitTask().PumpingWait();
                squiggleWaiter.CreateWaitTask().PumpingWait();

                taggerSource.TestOnly_Dispose();

                registrationService.Unregister(workspace);
            }
        }
        public void Test_TagSourceDiffer()
        {
            using (var workspace = CSharpWorkspaceFactory.CreateWorkspaceFromFiles(new string[] { "class A { }", "class E { }" }, CSharpParseOptions.Default))
            {
                var registrationService = workspace.Services.GetService<IWorkCoordinatorRegistrationService>();
                registrationService.Register(workspace);

                var diagnosticWaiter = new DiagnosticServiceWaiter();
                var squiggleWaiter = new ErrorSquiggleWaiter();

                Analyzer analyzer;
                DiagnosticAnalyzerService analyzerService;
                DiagnosticsSquiggleTaggerProvider.TagSource taggerSource;
                GetTagSource(workspace, diagnosticWaiter, squiggleWaiter, out analyzer, out analyzerService, out taggerSource);

                taggerSource.TagsChangedForBuffer += (o, arg) =>
                {
                    Assert.True(arg.Spans.First().Span.Contains(new Span(0, 1)));
                };

                var solutionWorkCoordinator = workspace.Services.GetService<IWorkCoordinatorRegistrationService>() as WorkCoordinatorRegistrationService;
                var incrementalAnalyzers = ImmutableArray.Create(analyzerService.CreateIncrementalAnalyzer(workspace));

                // test first update
                solutionWorkCoordinator.WaitUntilCompletion_ForTestingPurposesOnly(workspace, incrementalAnalyzers);

                diagnosticWaiter.CreateWaitTask().PumpingWait();
                squiggleWaiter.CreateWaitTask().PumpingWait();

                // test second update
                analyzer.ChangeSeverity();

                var document = workspace.CurrentSolution.GetDocument(workspace.Documents.First().Id);
                var text = document.GetTextAsync().Result;
                workspace.TryApplyChanges(document.WithText(text.WithChanges(new TextChange(new TextSpan(text.Length - 1, 1), string.Empty))).Project.Solution);

                solutionWorkCoordinator.WaitUntilCompletion_ForTestingPurposesOnly(workspace, incrementalAnalyzers);

                diagnosticWaiter.CreateWaitTask().PumpingWait();
                squiggleWaiter.CreateWaitTask().PumpingWait();

                taggerSource.TestOnly_Dispose();

                registrationService.Unregister(workspace);
            }
        }
Example #7
0
        public void TestPreviewDiagnosticTagger()
        {
            using (var workspace = CSharpWorkspaceFactory.CreateWorkspaceFromLines("class { }"))
                using (var previewWorkspace = new PreviewWorkspace(workspace.CurrentSolution))
                {
                    // set up to listen diagnostic changes so that we can wait until it happens
                    var diagnosticService = workspace.ExportProvider.GetExportedValue <IDiagnosticService>() as DiagnosticService;
                    var taskSource        = new TaskCompletionSource <DiagnosticsUpdatedArgs>();
                    diagnosticService.DiagnosticsUpdated += (s, a) => taskSource.TrySetResult(a);

                    // preview workspace and owner of the solution now share solution and its underlying text buffer
                    var hostDocument = workspace.Projects.First().Documents.First();
                    var buffer       = hostDocument.GetTextBuffer();

                    // enable preview diagnostics
                    previewWorkspace.OpenDocument(hostDocument.Id);
                    previewWorkspace.EnableDiagnostic();

                    var foregroundService = new TestForegroundNotificationService();
                    var optionsService    = workspace.Services.GetService <IOptionService>();
                    var squiggleWaiter    = new ErrorSquiggleWaiter();

                    // create a tagger for preview workspace
                    var taggerSource = new DiagnosticsSquiggleTaggerProvider.TagSource(buffer, foregroundService, diagnosticService, optionsService, squiggleWaiter);

                    // wait up to 20 seconds for diagnostic service
                    taskSource.Task.Wait(20000);
                    if (!taskSource.Task.IsCompleted)
                    {
                        // something is wrong
                        FatalError.Report(new System.Exception("not finished after 20 seconds"));
                    }

                    // wait for tagger
                    squiggleWaiter.CreateWaitTask().PumpingWait();

                    var snapshot     = buffer.CurrentSnapshot;
                    var intervalTree = taggerSource.GetTagIntervalTreeForBuffer(buffer);
                    var spans        = intervalTree.GetIntersectingSpans(new SnapshotSpan(snapshot, 0, snapshot.Length));

                    taggerSource.TestOnly_Dispose();

                    Assert.Equal(1, spans.Count);
                }
        }
        private static void GetTagSource(TestWorkspace workspace, DiagnosticServiceWaiter diagnosticWaiter, ErrorSquiggleWaiter squiggleWaiter, out Analyzer analyzer, out DiagnosticAnalyzerService analyzerService, out DiagnosticsSquiggleTaggerProvider.TagSource taggerSource)
        {
            analyzer = new Analyzer();
            var analyzerMap = new Dictionary<string, ImmutableArray<DiagnosticAnalyzer>>() { { LanguageNames.CSharp, ImmutableArray.Create<DiagnosticAnalyzer>(analyzer) } };
            analyzerService = new DiagnosticAnalyzerService(analyzerMap.ToImmutableDictionary());

            var diagnosticListeners = SpecializedCollections.SingletonEnumerable(new Lazy<IAsynchronousOperationListener, FeatureMetadata>(
                    () => diagnosticWaiter, new FeatureMetadata(new Dictionary<string, object>() { { "FeatureName", FeatureAttribute.DiagnosticService } })));

            var diagnosticService = new DiagnosticService(SpecializedCollections.SingletonEnumerable<IDiagnosticUpdateSource>(analyzerService), diagnosticListeners);

            var document = workspace.Documents.First();
            var buffer = document.GetTextBuffer();

            var foregroundService = new TestForegroundNotificationService();
            var optionsService = workspace.Services.GetService<IOptionService>();
            taggerSource = new DiagnosticsSquiggleTaggerProvider.TagSource(buffer, foregroundService, diagnosticService, optionsService, squiggleWaiter);
        }
Example #9
0
        public async Task TestPreviewDiagnosticTaggerInPreviewPane()
        {
            using (var workspace = TestWorkspace.CreateCSharp("class { }", exportProvider: EditorServicesUtil.ExportProvider))
            {
                // set up listener to wait until diagnostic finish running
                var diagnosticService = workspace.ExportProvider.GetExportedValue <IDiagnosticService>() as DiagnosticService;

                // no easy way to setup waiter. kind of hacky way to setup waiter
                var source     = new CancellationTokenSource();
                var taskSource = new TaskCompletionSource <DiagnosticsUpdatedArgs>();
                diagnosticService.DiagnosticsUpdated += (s, a) =>
                {
                    source.Cancel();

                    source = new CancellationTokenSource();
                    var cancellationToken = source.Token;
                    Task.Delay(2000, cancellationToken).ContinueWith(t => taskSource.TrySetResult(a), CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Current);
                };

                var hostDocument = workspace.Projects.First().Documents.First();

                // make a change to remove squiggle
                var oldDocument = workspace.CurrentSolution.GetDocument(hostDocument.Id);
                var oldText     = oldDocument.GetTextAsync().Result;

                var newDocument = oldDocument.WithText(oldText.WithChanges(new TextChange(new TextSpan(0, oldText.Length), "class C { }")));

                // create a diff view
                WpfTestCase.RequireWpfFact($"{nameof(TestPreviewDiagnosticTaggerInPreviewPane)} creates a {nameof(DifferenceViewerPreview)}");

                var previewFactoryService = workspace.ExportProvider.GetExportedValue <IPreviewFactoryService>();
                using (var diffView = (DifferenceViewerPreview)(await previewFactoryService.CreateChangedDocumentPreviewViewAsync(oldDocument, newDocument, CancellationToken.None)))
                {
                    var foregroundService = workspace.GetService <IForegroundNotificationService>();

                    var waiter    = new ErrorSquiggleWaiter();
                    var listeners = AsynchronousOperationListener.CreateListeners(FeatureAttribute.ErrorSquiggles, waiter);

                    // set up tagger for both buffers
                    var leftBuffer   = diffView.Viewer.LeftView.BufferGraph.GetTextBuffers(t => t.ContentType.IsOfType(ContentTypeNames.CSharpContentType)).First();
                    var leftProvider = new DiagnosticsSquiggleTaggerProvider(diagnosticService, foregroundService, listeners);
                    var leftTagger   = leftProvider.CreateTagger <IErrorTag>(leftBuffer);
                    using (var leftDisposable = leftTagger as IDisposable)
                    {
                        var rightBuffer   = diffView.Viewer.RightView.BufferGraph.GetTextBuffers(t => t.ContentType.IsOfType(ContentTypeNames.CSharpContentType)).First();
                        var rightProvider = new DiagnosticsSquiggleTaggerProvider(diagnosticService, foregroundService, listeners);
                        var rightTagger   = rightProvider.CreateTagger <IErrorTag>(rightBuffer);
                        using (var rightDisposable = rightTagger as IDisposable)
                        {
                            // wait up to 20 seconds for diagnostics
                            taskSource.Task.Wait(20000);
                            if (!taskSource.Task.IsCompleted)
                            {
                                // something is wrong
                                FatalError.Report(new System.Exception("not finished after 20 seconds"));
                            }

                            // wait taggers
                            await waiter.CreateWaitTask();

                            // check left buffer
                            var leftSnapshot = leftBuffer.CurrentSnapshot;
                            var leftSpans    = leftTagger.GetTags(leftSnapshot.GetSnapshotSpanCollection()).ToList();
                            Assert.Equal(1, leftSpans.Count);

                            // check right buffer
                            var rightSnapshot = rightBuffer.CurrentSnapshot;
                            var rightSpans    = rightTagger.GetTags(rightSnapshot.GetSnapshotSpanCollection()).ToList();
                            Assert.Equal(0, rightSpans.Count);
                        }
                    }
                }
            }
        }
        public void TestPreviewDiagnosticTaggerInPreviewPane()
        {
            using (var workspace = CSharpWorkspaceFactory.CreateWorkspaceFromLines("class { }"))
            {
                // set up listener to wait until diagnostic finish running
                var diagnosticService = workspace.ExportProvider.GetExportedValue<IDiagnosticService>() as DiagnosticService;

                // no easy way to setup waiter. kind of hacky way to setup waiter
                var source = new CancellationTokenSource();
                var taskSource = new TaskCompletionSource<DiagnosticsUpdatedArgs>();
                diagnosticService.DiagnosticsUpdated += (s, a) =>
                {
                    source.Cancel();

                    source = new CancellationTokenSource();
                    var cancellationToken = source.Token;
                    Task.Delay(2000, cancellationToken).ContinueWith(t => taskSource.TrySetResult(a), TaskContinuationOptions.OnlyOnRanToCompletion);
                };

                var hostDocument = workspace.Projects.First().Documents.First();

                // make a change to remove squiggle
                var oldDocument = workspace.CurrentSolution.GetDocument(hostDocument.Id);
                var oldText = oldDocument.GetTextAsync().Result;

                var newDocument = oldDocument.WithText(oldText.WithChanges(new TextChange(new TextSpan(0, oldText.Length), "class C { }")));

                // create a diff view
                var previewFactoryService = workspace.ExportProvider.GetExportedValue<IPreviewFactoryService>();
                var diffView = previewFactoryService.CreateChangedDocumentPreviewView(oldDocument, newDocument, CancellationToken.None);

                var foregroundService = new TestForegroundNotificationService();
                var optionsService = workspace.Services.GetService<IOptionService>();

                // set up tagger for both buffers
                var leftBuffer = diffView.LeftView.BufferGraph.GetTextBuffers(t => t.ContentType.IsOfType(ContentTypeNames.CSharpContentType)).First();
                var leftWaiter = new ErrorSquiggleWaiter();
                var leftTaggerSource = new DiagnosticsSquiggleTaggerProvider.TagSource(leftBuffer, foregroundService, diagnosticService, optionsService, leftWaiter);

                var rightBuffer = diffView.RightView.BufferGraph.GetTextBuffers(t => t.ContentType.IsOfType(ContentTypeNames.CSharpContentType)).First();
                var rightWaiter = new ErrorSquiggleWaiter();
                var rightTaggerSource = new DiagnosticsSquiggleTaggerProvider.TagSource(rightBuffer, foregroundService, diagnosticService, optionsService, rightWaiter);

                // wait up to 20 seconds for diagnostics
                taskSource.Task.Wait(20000);
                if (!taskSource.Task.IsCompleted)
                {
                    // something is wrong
                    FatalError.Report(new System.Exception("not finished after 20 seconds"));
                }

                // wait taggers
                leftWaiter.CreateWaitTask().PumpingWait();
                rightWaiter.CreateWaitTask().PumpingWait();

                // check left buffer
                var leftSnapshot = leftBuffer.CurrentSnapshot;
                var leftIntervalTree = leftTaggerSource.GetTagIntervalTreeForBuffer(leftBuffer);
                var leftSpans = leftIntervalTree.GetIntersectingSpans(new SnapshotSpan(leftSnapshot, 0, leftSnapshot.Length));

                leftTaggerSource.TestOnly_Dispose();
                Assert.Equal(1, leftSpans.Count);

                // check right buffer
                var rightSnapshot = rightBuffer.CurrentSnapshot;
                var rightIntervalTree = rightTaggerSource.GetTagIntervalTreeForBuffer(rightBuffer);
                var rightSpans = rightIntervalTree.GetIntersectingSpans(new SnapshotSpan(rightSnapshot, 0, rightSnapshot.Length));

                rightTaggerSource.TestOnly_Dispose();
                Assert.Equal(0, rightSpans == null ? 0 : rightSpans.Count);
            }
        }
        public void TestPreviewDiagnosticTagger()
        {
            using (var workspace = CSharpWorkspaceFactory.CreateWorkspaceFromLines("class { }"))
            using (var previewWorkspace = new PreviewWorkspace(workspace.CurrentSolution))
            {
                // set up to listen diagnostic changes so that we can wait until it happens
                var diagnosticService = workspace.ExportProvider.GetExportedValue<IDiagnosticService>() as DiagnosticService;
                var taskSource = new TaskCompletionSource<DiagnosticsUpdatedArgs>();
                diagnosticService.DiagnosticsUpdated += (s, a) => taskSource.TrySetResult(a);

                // preview workspace and owner of the solution now share solution and its underlying text buffer
                var hostDocument = workspace.Projects.First().Documents.First();
                var buffer = hostDocument.GetTextBuffer();

                // enable preview diagnostics
                previewWorkspace.OpenDocument(hostDocument.Id);
                previewWorkspace.EnableDiagnostic();

                var foregroundService = new TestForegroundNotificationService();
                var optionsService = workspace.Services.GetService<IOptionService>();
                var squiggleWaiter = new ErrorSquiggleWaiter();

                // create a tagger for preview workspace
                var taggerSource = new DiagnosticsSquiggleTaggerProvider.TagSource(buffer, foregroundService, diagnosticService, optionsService, squiggleWaiter);

                // wait up to 20 seconds for diagnostic service
                taskSource.Task.Wait(20000);
                if (!taskSource.Task.IsCompleted)
                {
                    // something is wrong
                    FatalError.Report(new System.Exception("not finished after 20 seconds"));
                }

                // wait for tagger
                squiggleWaiter.CreateWaitTask().PumpingWait();

                var snapshot = buffer.CurrentSnapshot;
                var intervalTree = taggerSource.GetTagIntervalTreeForBuffer(buffer);
                var spans = intervalTree.GetIntersectingSpans(new SnapshotSpan(snapshot, 0, snapshot.Length));

                taggerSource.TestOnly_Dispose();

                Assert.Equal(1, spans.Count);
            }
        }
Example #12
0
        public async Task TestPreviewDiagnosticTaggerInPreviewPane()
        {
            using (var workspace = await TestWorkspace.CreateCSharpAsync("class { }"))
            {
                // set up listener to wait until diagnostic finish running
                var diagnosticService = workspace.ExportProvider.GetExportedValue<IDiagnosticService>() as DiagnosticService;

                // no easy way to setup waiter. kind of hacky way to setup waiter
                var source = new CancellationTokenSource();
                var taskSource = new TaskCompletionSource<DiagnosticsUpdatedArgs>();
                diagnosticService.DiagnosticsUpdated += (s, a) =>
                {
                    source.Cancel();

                    source = new CancellationTokenSource();
                    var cancellationToken = source.Token;
                    Task.Delay(2000, cancellationToken).ContinueWith(t => taskSource.TrySetResult(a), CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Current);
                };

                var hostDocument = workspace.Projects.First().Documents.First();

                // make a change to remove squiggle
                var oldDocument = workspace.CurrentSolution.GetDocument(hostDocument.Id);
                var oldText = oldDocument.GetTextAsync().Result;

                var newDocument = oldDocument.WithText(oldText.WithChanges(new TextChange(new TextSpan(0, oldText.Length), "class C { }")));

                // create a diff view
                WpfTestCase.RequireWpfFact($"{nameof(TestPreviewDiagnosticTaggerInPreviewPane)} creates a {nameof(DifferenceViewerPreview)}");

                var previewFactoryService = workspace.ExportProvider.GetExportedValue<IPreviewFactoryService>();
                using (var diffView = (DifferenceViewerPreview)(await previewFactoryService.CreateChangedDocumentPreviewViewAsync(oldDocument, newDocument, CancellationToken.None)))
                {
                    var foregroundService = workspace.GetService<IForegroundNotificationService>();

                    var waiter = new ErrorSquiggleWaiter();
                    var listeners = AsynchronousOperationListener.CreateListeners(FeatureAttribute.ErrorSquiggles, waiter);

                    // set up tagger for both buffers
                    var leftBuffer = diffView.Viewer.LeftView.BufferGraph.GetTextBuffers(t => t.ContentType.IsOfType(ContentTypeNames.CSharpContentType)).First();
                    var leftProvider = new DiagnosticsSquiggleTaggerProvider(diagnosticService, foregroundService, listeners);
                    var leftTagger = leftProvider.CreateTagger<IErrorTag>(leftBuffer);
                    using (var leftDisposable = leftTagger as IDisposable)
                    {
                        var rightBuffer = diffView.Viewer.RightView.BufferGraph.GetTextBuffers(t => t.ContentType.IsOfType(ContentTypeNames.CSharpContentType)).First();
                        var rightProvider = new DiagnosticsSquiggleTaggerProvider(diagnosticService, foregroundService, listeners);
                        var rightTagger = rightProvider.CreateTagger<IErrorTag>(rightBuffer);
                        using (var rightDisposable = rightTagger as IDisposable)
                        {
                            // wait up to 20 seconds for diagnostics
                            taskSource.Task.Wait(20000);
                            if (!taskSource.Task.IsCompleted)
                            {
                                // something is wrong
                                FatalError.Report(new System.Exception("not finished after 20 seconds"));
                            }

                            // wait taggers
                            await waiter.CreateWaitTask();

                            // check left buffer
                            var leftSnapshot = leftBuffer.CurrentSnapshot;
                            var leftSpans = leftTagger.GetTags(leftSnapshot.GetSnapshotSpanCollection()).ToList();
                            Assert.Equal(1, leftSpans.Count);

                            // check right buffer
                            var rightSnapshot = rightBuffer.CurrentSnapshot;
                            var rightSpans = rightTagger.GetTags(rightSnapshot.GetSnapshotSpanCollection()).ToList();
                            Assert.Equal(0, rightSpans.Count);
                        }
                    }
                }
            }
        }
        private static void GetTagSource(TestWorkspace workspace, DiagnosticServiceWaiter diagnosticWaiter, ErrorSquiggleWaiter squiggleWaiter, out Analyzer analyzer, out DiagnosticAnalyzerService analyzerService, out DiagnosticsSquiggleTaggerProvider.TagSource taggerSource)
        {
            analyzer = new Analyzer();
            var analyzerMap = new Dictionary <string, ImmutableArray <DiagnosticAnalyzer> >()
            {
                { LanguageNames.CSharp, ImmutableArray.Create <DiagnosticAnalyzer>(analyzer) }
            };

            analyzerService = new DiagnosticAnalyzerService(analyzerMap.ToImmutableDictionary());

            var diagnosticListeners = SpecializedCollections.SingletonEnumerable(new Lazy <IAsynchronousOperationListener, FeatureMetadata>(
                                                                                     () => diagnosticWaiter, new FeatureMetadata(new Dictionary <string, object>()
            {
                { "FeatureName", FeatureAttribute.DiagnosticService }
            })));

            var diagnosticService = new DiagnosticService(SpecializedCollections.SingletonEnumerable <IDiagnosticUpdateSource>(analyzerService), diagnosticListeners);

            var document = workspace.Documents.First();
            var buffer   = document.GetTextBuffer();

            var foregroundService = new TestForegroundNotificationService();
            var optionsService    = workspace.Services.GetService <IOptionService>();

            taggerSource = new DiagnosticsSquiggleTaggerProvider.TagSource(buffer, foregroundService, diagnosticService, optionsService, squiggleWaiter);
        }
Example #14
0
        public void TestPreviewDiagnosticTaggerInPreviewPane()
        {
            using (var workspace = CSharpWorkspaceFactory.CreateWorkspaceFromLines("class { }"))
            {
                // set up listener to wait until diagnostic finish running
                var diagnosticService = workspace.ExportProvider.GetExportedValue <IDiagnosticService>() as DiagnosticService;

                // no easy way to setup waiter. kind of hacky way to setup waiter
                var source     = new CancellationTokenSource();
                var taskSource = new TaskCompletionSource <DiagnosticsUpdatedArgs>();
                diagnosticService.DiagnosticsUpdated += (s, a) =>
                {
                    source.Cancel();

                    source = new CancellationTokenSource();
                    var cancellationToken = source.Token;
                    Task.Delay(2000, cancellationToken).ContinueWith(t => taskSource.TrySetResult(a), CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Current);
                };

                var hostDocument = workspace.Projects.First().Documents.First();

                // make a change to remove squiggle
                var oldDocument = workspace.CurrentSolution.GetDocument(hostDocument.Id);
                var oldText     = oldDocument.GetTextAsync().Result;

                var newDocument = oldDocument.WithText(oldText.WithChanges(new TextChange(new TextSpan(0, oldText.Length), "class C { }")));

                // create a diff view
                var previewFactoryService = workspace.ExportProvider.GetExportedValue <IPreviewFactoryService>();
                var diffView = (IWpfDifferenceViewer)previewFactoryService.CreateChangedDocumentPreviewViewAsync(oldDocument, newDocument, CancellationToken.None).PumpingWaitResult();

                var foregroundService = new TestForegroundNotificationService();
                var optionsService    = workspace.Services.GetService <IOptionService>();

                // set up tagger for both buffers
                var leftBuffer       = diffView.LeftView.BufferGraph.GetTextBuffers(t => t.ContentType.IsOfType(ContentTypeNames.CSharpContentType)).First();
                var leftWaiter       = new ErrorSquiggleWaiter();
                var leftTaggerSource = new DiagnosticsSquiggleTaggerProvider.TagSource(leftBuffer, foregroundService, diagnosticService, optionsService, leftWaiter);

                var rightBuffer       = diffView.RightView.BufferGraph.GetTextBuffers(t => t.ContentType.IsOfType(ContentTypeNames.CSharpContentType)).First();
                var rightWaiter       = new ErrorSquiggleWaiter();
                var rightTaggerSource = new DiagnosticsSquiggleTaggerProvider.TagSource(rightBuffer, foregroundService, diagnosticService, optionsService, rightWaiter);

                // wait up to 20 seconds for diagnostics
                taskSource.Task.Wait(20000);
                if (!taskSource.Task.IsCompleted)
                {
                    // something is wrong
                    FatalError.Report(new System.Exception("not finished after 20 seconds"));
                }

                // wait taggers
                leftWaiter.CreateWaitTask().PumpingWait();
                rightWaiter.CreateWaitTask().PumpingWait();

                // check left buffer
                var leftSnapshot     = leftBuffer.CurrentSnapshot;
                var leftIntervalTree = leftTaggerSource.GetTagIntervalTreeForBuffer(leftBuffer);
                var leftSpans        = leftIntervalTree.GetIntersectingSpans(new SnapshotSpan(leftSnapshot, 0, leftSnapshot.Length));

                leftTaggerSource.TestOnly_Dispose();
                Assert.Equal(1, leftSpans.Count);

                // check right buffer
                var rightSnapshot     = rightBuffer.CurrentSnapshot;
                var rightIntervalTree = rightTaggerSource.GetTagIntervalTreeForBuffer(rightBuffer);
                var rightSpans        = rightIntervalTree.GetIntersectingSpans(new SnapshotSpan(rightSnapshot, 0, rightSnapshot.Length));

                rightTaggerSource.TestOnly_Dispose();
                Assert.Equal(0, rightSpans == null ? 0 : rightSpans.Count);
            }
        }