private DiagnosticTaggerWrapper(TestWorkspace workspace, DiagnosticAnalyzerService analyzerService, IDiagnosticUpdateSource updateSource)
        {
            if (updateSource == null)
            {
                updateSource = analyzerService;
            }

            this.workspace = workspace;

            this.registrationService = workspace.Services.GetService <ISolutionCrawlerRegistrationService>();
            registrationService.Register(workspace);

            this.asyncListener = new AsynchronousOperationListener();
            var listeners = AsynchronousOperationListener.CreateListeners(
                ValueTuple.Create(FeatureAttribute.DiagnosticService, asyncListener),
                ValueTuple.Create(FeatureAttribute.ErrorSquiggles, asyncListener));

            this.analyzerService = analyzerService;
            var diagnosticService = new DiagnosticService(SpecializedCollections.SingletonEnumerable(updateSource), listeners);

            this.TaggerProvider = new DiagnosticsSquiggleTaggerProvider(
                workspace.Services.GetService <IOptionService>(), diagnosticService,
                workspace.GetService <IForegroundNotificationService>(), listeners);

            if (analyzerService != null)
            {
                this.incrementalAnalyzers   = ImmutableArray.Create(analyzerService.CreateIncrementalAnalyzer(workspace));
                this.solutionCrawlerService = workspace.Services.GetService <ISolutionCrawlerRegistrationService>() as SolutionCrawlerRegistrationService;
            }
        }
        private DiagnosticTaggerWrapper(TestWorkspace workspace, DiagnosticAnalyzerService analyzerService, IDiagnosticUpdateSource updateSource)
        {
            if (updateSource == null)
            {
                updateSource = analyzerService;
            }

            this.workspace = workspace;

            this.registrationService = workspace.Services.GetService<ISolutionCrawlerRegistrationService>();
            registrationService.Register(workspace);

            this.asyncListener = new AsynchronousOperationListener();
            var listeners = AsynchronousOperationListener.CreateListeners(
                ValueTuple.Create(FeatureAttribute.DiagnosticService, asyncListener),
                ValueTuple.Create(FeatureAttribute.ErrorSquiggles, asyncListener));

            this.analyzerService = analyzerService;
            var diagnosticService = new DiagnosticService(SpecializedCollections.SingletonEnumerable(updateSource), listeners);

            this.TaggerProvider = new DiagnosticsSquiggleTaggerProvider(
                workspace.Services.GetService<IOptionService>(), diagnosticService,
                workspace.GetService<IForegroundNotificationService>(), listeners);

            if (analyzerService != null)
            {
                this.incrementalAnalyzers = ImmutableArray.Create(analyzerService.CreateIncrementalAnalyzer(workspace));
                this.solutionCrawlerService = workspace.Services.GetService<ISolutionCrawlerRegistrationService>() as SolutionCrawlerRegistrationService;
            }
        }
        internal static IList <ITagSpan <IErrorTag> > GetErrorsFromUpdateSource(TestWorkspace workspace, TestHostDocument document, DiagnosticsUpdatedArgs updateArgs)
        {
            var source = new TestDiagnosticUpdateSource();

            var listener  = new AsynchronousOperationListener();
            var listeners = AsynchronousOperationListener.CreateListeners(
                ValueTuple.Create(FeatureAttribute.DiagnosticService, listener),
                ValueTuple.Create(FeatureAttribute.ErrorSquiggles, listener));

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

            var foregroundService = workspace.GetService <IForegroundNotificationService>();  //new TestForegroundNotificationService();

            var buffer   = document.GetTextBuffer();
            var provider = new DiagnosticsSquiggleTaggerProvider(optionsService, diagnosticService, foregroundService, listeners);
            var tagger   = provider.CreateTagger <IErrorTag>(buffer);

            using (var disposable = tagger as IDisposable)
            {
                source.RaiseDiagnosticsUpdated(updateArgs);

                listener.CreateWaitTask().PumpingWait();

                var snapshot = buffer.CurrentSnapshot;
                var spans    = tagger.GetTags(new NormalizedSnapshotSpanCollection(new SnapshotSpan(snapshot, 0, snapshot.Length))).ToImmutableArray();

                return(spans);
            }
        }
Esempio n. 4
0
        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 analyzer        = new Analyzer();
                var analyzerService = new TestDiagnosticAnalyzerService(
                    new Dictionary <string, ImmutableArray <DiagnosticAnalyzer> >()
                {
                    { LanguageNames.CSharp, ImmutableArray.Create <DiagnosticAnalyzer>(analyzer) }
                }.ToImmutableDictionary());

                var listener  = new AsynchronousOperationListener();
                var listeners = AsynchronousOperationListener.CreateListeners(
                    ValueTuple.Create(FeatureAttribute.DiagnosticService, listener),
                    ValueTuple.Create(FeatureAttribute.ErrorSquiggles, listener));

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

                var provider = new DiagnosticsSquiggleTaggerProvider(
                    workspace.Services.GetService <IOptionService>(), diagnosticService,
                    workspace.GetService <IForegroundNotificationService>(), listeners);
                var tagger = provider.CreateTagger <IErrorTag>(workspace.Documents.First().GetTextBuffer());
                using (var disposable = tagger as IDisposable)
                {
                    var service = workspace.Services.GetService <ISolutionCrawlerRegistrationService>() as SolutionCrawlerRegistrationService;
                    var incrementalAnalyzers = ImmutableArray.Create(analyzerService.CreateIncrementalAnalyzer(workspace));

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

                    listener.CreateWaitTask().PumpingWait();

                    var snapshot = workspace.Documents.First().GetTextBuffer().CurrentSnapshot;
                    var spans    = tagger.GetTags(new NormalizedSnapshotSpanCollection(new SnapshotSpan(snapshot, 0, snapshot.Length))).ToList();
                    Assert.True(spans.First().Span.Contains(new Span(0, 1)));

                    // 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);

                    listener.CreateWaitTask().PumpingWait();

                    snapshot = workspace.Documents.First().GetTextBuffer().CurrentSnapshot;
                    spans    = tagger.GetTags(new NormalizedSnapshotSpanCollection(new SnapshotSpan(snapshot, 0, snapshot.Length))).ToList();
                    Assert.True(spans.First().Span.Contains(new Span(0, 1)));

                    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<ISolutionCrawlerRegistrationService>();
                registrationService.Register(workspace);

                var analyzer = new Analyzer();
                var analyzerService = new TestDiagnosticAnalyzerService(
                    new Dictionary<string, ImmutableArray<DiagnosticAnalyzer>>() { { LanguageNames.CSharp, ImmutableArray.Create<DiagnosticAnalyzer>(analyzer) } }.ToImmutableDictionary());

                var listener = new AsynchronousOperationListener();
                var listeners = AsynchronousOperationListener.CreateListeners(
                    ValueTuple.Create(FeatureAttribute.DiagnosticService, listener),
                    ValueTuple.Create(FeatureAttribute.ErrorSquiggles, listener));

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

                var provider = new DiagnosticsSquiggleTaggerProvider(
                    workspace.Services.GetService<IOptionService>(), diagnosticService,
                    workspace.GetService<IForegroundNotificationService>(), listeners);
                var tagger = provider.CreateTagger<IErrorTag>(workspace.Documents.First().GetTextBuffer());
                using (var disposable = tagger as IDisposable)
                {

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

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

                    listener.CreateWaitTask().PumpingWait();

                    var snapshot = workspace.Documents.First().GetTextBuffer().CurrentSnapshot;
                    var spans = tagger.GetTags(new NormalizedSnapshotSpanCollection(new SnapshotSpan(snapshot, 0, snapshot.Length))).ToList();
                    Assert.True(spans.First().Span.Contains(new Span(0, 1)));

                    // 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);

                    listener.CreateWaitTask().PumpingWait();

                    snapshot = workspace.Documents.First().GetTextBuffer().CurrentSnapshot;
                    spans = tagger.GetTags(new NormalizedSnapshotSpanCollection(new SnapshotSpan(snapshot, 0, snapshot.Length))).ToList();
                    Assert.True(spans.First().Span.Contains(new Span(0, 1)));

                    registrationService.Unregister(workspace);
                }
            }
        }
Esempio n. 6
0
        public async Task TestPreviewDiagnosticTaggerInPreviewPane()
        {
            using var workspace = TestWorkspace.CreateCSharp("class { }", exportProvider: EditorServicesUtil.ExportProvider);

            workspace.TryApplyChanges(workspace.CurrentSolution.WithAnalyzerReferences(new[] { DiagnosticExtensions.GetCompilerDiagnosticAnalyzerReference(LanguageNames.CSharp) }));

            // set up listener to wait until diagnostic finish running
            var diagnosticService = workspace.ExportProvider.GetExportedValue <IDiagnosticService>();

            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
            WpfTestRunner.RequireWpfFact($"{nameof(TestPreviewDiagnosticTaggerInPreviewPane)} creates a {nameof(DifferenceViewerPreview)}");

            var previewFactoryService = (PreviewFactoryService)workspace.ExportProvider.GetExportedValue <IPreviewFactoryService>();

            using var diffView = await previewFactoryService.CreateChangedDocumentPreviewViewAsync(oldDocument, newDocument, CancellationToken.None);

            var foregroundService = workspace.GetService <IForegroundNotificationService>();

            var listenerProvider = workspace.ExportProvider.GetExportedValue <AsynchronousOperationListenerProvider>();

            // set up tagger for both buffers
            var leftBuffer   = diffView.Viewer.LeftView.BufferGraph.GetTextBuffers(t => t.ContentType.IsOfType(ContentTypeNames.CSharpContentType)).First();
            var leftProvider = new DiagnosticsSquiggleTaggerProvider(workspace.ExportProvider.GetExportedValue <IThreadingContext>(), diagnosticService, foregroundService, listenerProvider);
            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(workspace.ExportProvider.GetExportedValue <IThreadingContext>(), diagnosticService, foregroundService, listenerProvider);
            var rightTagger   = rightProvider.CreateTagger <IErrorTag>(rightBuffer);

            using var rightDisposable = rightTagger as IDisposable;
            // wait for diagnostics and taggers
            await listenerProvider.WaitAllDispatcherOperationAndTasksAsync(FeatureAttribute.DiagnosticService, FeatureAttribute.ErrorSquiggles);

            // 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);
        }
        internal static List <ITagSpan <IErrorTag> > GetErrorSpans(
            TestWorkspace workspace,
            ImmutableDictionary <string, ImmutableArray <DiagnosticAnalyzer> > analyzerMap = null)
        {
            var registrationService = workspace.Services.GetService <ISolutionCrawlerRegistrationService>();

            registrationService.Register(workspace);

            var listener  = new AsynchronousOperationListener();
            var listeners = AsynchronousOperationListener.CreateListeners(
                ValueTuple.Create(FeatureAttribute.DiagnosticService, listener),
                ValueTuple.Create(FeatureAttribute.ErrorSquiggles, listener));

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

            var analyzerService = analyzerMap == null || analyzerMap.Count == 0
                ? new TestDiagnosticAnalyzerService(DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap())
                : new TestDiagnosticAnalyzerService(analyzerMap);

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

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

            var foregroundService = workspace.GetService <IForegroundNotificationService>();
            var taggerProvider    = new DiagnosticsSquiggleTaggerProvider(optionsService, diagnosticService, foregroundService, listeners);
            var tagger            = taggerProvider.CreateTagger <IErrorTag>(buffer);

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

                listener.CreateWaitTask().PumpingWait();

                var snapshot = buffer.CurrentSnapshot;
                var spans    = tagger.GetTags(new NormalizedSnapshotSpanCollection(new SnapshotSpan(snapshot, 0, snapshot.Length))).ToList();

                registrationService.Unregister(workspace);

                return(spans);
            }
        }
        public async Task TestWithMockDiagnosticService_TaggerProviderCreatedBeforeInitialDiagnosticsReported()
        {
            // This test produces diagnostics from a mock service so that we are disconnected from
            // all teh asynchrony of hte actual async analyzer engine.  If this fails, then the
            // issue is almost certainly in the DiagnosticsSquiggleTaggerProvider code.  If this
            // succeed, but other squiggle tests fail, then it is likely an issue with the
            // diagnostics engine not actually reporting all diagnostics properly.

            using (var workspace = await TestWorkspace.CreateCSharpAsync(new string[] { "class A { }" }, CSharpParseOptions.Default))
                using (var wrapper = new DiagnosticTaggerWrapper(workspace))
                {
                    var asyncListener = new AsynchronousOperationListener();
                    var listeners     = AsynchronousOperationListener.CreateListeners(
                        ValueTuple.Create(FeatureAttribute.DiagnosticService, asyncListener),
                        ValueTuple.Create(FeatureAttribute.ErrorSquiggles, asyncListener));

                    var diagnosticService = new MockDiagnosticService(workspace);
                    var provider          = new DiagnosticsSquiggleTaggerProvider(
                        workspace.Services.GetService <IOptionService>(), diagnosticService,
                        workspace.GetService <IForegroundNotificationService>(), listeners);

                    // Create the tagger before the first diagnostic event has been fired.
                    var tagger = provider.CreateTagger <IErrorTag>(workspace.Documents.First().GetTextBuffer());

                    // Now product hte first diagnostic and fire the events.
                    var tree = await workspace.CurrentSolution.Projects.Single().Documents.Single().GetSyntaxTreeAsync();

                    var span = TextSpan.FromBounds(0, 5);
                    diagnosticService.CreateDiagnosticAndFireEvents(Location.Create(tree, span));

                    using (var disposable = tagger as IDisposable)
                    {
                        await asyncListener.CreateWaitTask();

                        var snapshot = workspace.Documents.First().GetTextBuffer().CurrentSnapshot;
                        var spans    = tagger.GetTags(snapshot.GetSnapshotSpanCollection()).ToList();
                        Assert.Equal(1, spans.Count);
                        Assert.Equal(span.ToSpan(), spans[0].Span.Span);
                    }
                }
        }
        internal static List<ITagSpan<IErrorTag>> GetErrorSpans(
            TestWorkspace workspace,
            ImmutableDictionary<string, ImmutableArray<DiagnosticAnalyzer>> analyzerMap = null)
        {
            var registrationService = workspace.Services.GetService<ISolutionCrawlerRegistrationService>();
            registrationService.Register(workspace);

            var listener = new AsynchronousOperationListener();
            var listeners = AsynchronousOperationListener.CreateListeners(
                ValueTuple.Create(FeatureAttribute.DiagnosticService, listener),
                ValueTuple.Create(FeatureAttribute.ErrorSquiggles, listener));

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

            var analyzerService = analyzerMap == null || analyzerMap.Count == 0
                ? new TestDiagnosticAnalyzerService(DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap())
                : new TestDiagnosticAnalyzerService(analyzerMap);

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

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

            var foregroundService = workspace.GetService<IForegroundNotificationService>();
            var taggerProvider = new DiagnosticsSquiggleTaggerProvider(optionsService, diagnosticService, foregroundService, listeners);
            var tagger = taggerProvider.CreateTagger<IErrorTag>(buffer);
            using (var disposable = tagger as IDisposable)
            {
                var service = workspace.Services.GetService<ISolutionCrawlerRegistrationService>() as SolutionCrawlerRegistrationService;
                service.WaitUntilCompletion_ForTestingPurposesOnly(workspace, ImmutableArray.Create(analyzerService.CreateIncrementalAnalyzer(workspace)));

                listener.CreateWaitTask().PumpingWait();

                var snapshot = buffer.CurrentSnapshot;
                var spans = tagger.GetTags(new NormalizedSnapshotSpanCollection(new SnapshotSpan(snapshot, 0, snapshot.Length))).ToList();

                registrationService.Unregister(workspace);

                return spans;
            }
        }
Esempio n. 11
0
        public async Task TestWithMockDiagnosticService_TaggerProviderCreatedAfterInitialDiagnosticsReported()
        {
            // This test produces diagnostics from a mock service so that we are disconnected from
            // all the asynchrony of the actual async analyzer engine.  If this fails, then the
            // issue is almost certainly in the DiagnosticsSquiggleTaggerProvider code.  If this
            // succeed, but other squiggle tests fail, then it is likely an issue with the
            // diagnostics engine not actually reporting all diagnostics properly.

            using var workspace = TestWorkspace.CreateCSharp(new string[] { "class A { }" }, CSharpParseOptions.Default);
            using var wrapper   = new DiagnosticTaggerWrapper <DiagnosticsSquiggleTaggerProvider>(workspace);
            var listenerProvider = workspace.ExportProvider.GetExportedValue <IAsynchronousOperationListenerProvider>();

            var diagnosticService = new MockDiagnosticService(workspace);
            var provider          = new DiagnosticsSquiggleTaggerProvider(
                workspace.ExportProvider.GetExportedValue <IThreadingContext>(),
                diagnosticService,
                workspace.GetService <IForegroundNotificationService>(),
                listenerProvider);

            // Create and fire the diagnostic events before the tagger is even made.
            var tree = await workspace.CurrentSolution.Projects.Single().Documents.Single().GetRequiredSyntaxTreeAsync(CancellationToken.None);

            var span = TextSpan.FromBounds(0, 5);

            diagnosticService.CreateDiagnosticAndFireEvents(Location.Create(tree, span));

            var tagger = provider.CreateTagger <IErrorTag>(workspace.Documents.First().GetTextBuffer());

            using var disposable = tagger as IDisposable;
            await listenerProvider.GetWaiter(FeatureAttribute.DiagnosticService).ExpeditedWaitAsync();

            await listenerProvider.GetWaiter(FeatureAttribute.ErrorSquiggles).ExpeditedWaitAsync();

            var snapshot = workspace.Documents.First().GetTextBuffer().CurrentSnapshot;
            var spans    = tagger.GetTags(snapshot.GetSnapshotSpanCollection()).ToList();

            Assert.Equal(1, spans.Count);
            Assert.Equal(span.ToSpan(), spans[0].Span.Span);
        }
Esempio n. 12
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);
                        }
                    }
                }
            }
        }
        internal static IList<ITagSpan<IErrorTag>> GetErrorsFromUpdateSource(TestWorkspace workspace, TestHostDocument document, DiagnosticsUpdatedArgs updateArgs)
        {
            var source = new TestDiagnosticUpdateSource();

            var listener = new AsynchronousOperationListener();
            var listeners = AsynchronousOperationListener.CreateListeners(
                ValueTuple.Create(FeatureAttribute.DiagnosticService, listener),
                ValueTuple.Create(FeatureAttribute.ErrorSquiggles, listener));

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

            var foregroundService = workspace.GetService<IForegroundNotificationService>();  //new TestForegroundNotificationService();

            var buffer = document.GetTextBuffer();
            var provider = new DiagnosticsSquiggleTaggerProvider(optionsService, diagnosticService, foregroundService, listeners);
            var tagger = provider.CreateTagger<IErrorTag>(buffer);

            source.RaiseDiagnosticsUpdated(updateArgs);

            listener.CreateWaitTask().PumpingWait();

            var snapshot = buffer.CurrentSnapshot;
            var spans = tagger.GetTags(new NormalizedSnapshotSpanCollection(new SnapshotSpan(snapshot, 0, snapshot.Length))).ToImmutableArray();

            ((IDisposable)tagger).Dispose();

            return spans;
        }
Esempio n. 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 = workspace.GetService<IForegroundNotificationService>();
                var optionsService = workspace.Services.GetService<IOptionService>();

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

                // set up tagger for both buffers
                var leftBuffer = diffView.LeftView.BufferGraph.GetTextBuffers(t => t.ContentType.IsOfType(ContentTypeNames.CSharpContentType)).First();
                var leftProvider = new DiagnosticsSquiggleTaggerProvider(optionsService, diagnosticService, foregroundService, listeners);
                var leftTagger = leftProvider.CreateTagger<IErrorTag>(leftBuffer);
                using (var leftDisposable = leftTagger as IDisposable)
                {
                    var rightBuffer = diffView.RightView.BufferGraph.GetTextBuffers(t => t.ContentType.IsOfType(ContentTypeNames.CSharpContentType)).First();
                    var rightProvider = new DiagnosticsSquiggleTaggerProvider(optionsService, 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
                        waiter.CreateWaitTask().PumpingWait();

                        // 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 async Task TestWithMockDiagnosticService_TaggerProviderCreatedAfterInitialDiagnosticsReported()
        {
            // This test produces diagnostics from a mock service so that we are disconnected from
            // all teh asynchrony of hte actual async analyzer engine.  If this fails, then the 
            // issue is almost certainly in the DiagnosticsSquiggleTaggerProvider code.  If this
            // succeed, but other squiggle tests fail, then it is likely an issue with the 
            // diagnostics engine not actually reporting all diagnostics properly.

            using (var workspace = await TestWorkspace.CreateCSharpAsync(new string[] { "class A { }" }, CSharpParseOptions.Default))
            using (var wrapper = new DiagnosticTaggerWrapper(workspace))
            {
                var asyncListener = new AsynchronousOperationListener();
                var listeners = AsynchronousOperationListener.CreateListeners(
                    ValueTuple.Create(FeatureAttribute.DiagnosticService, asyncListener),
                    ValueTuple.Create(FeatureAttribute.ErrorSquiggles, asyncListener));

                var diagnosticService = new MockDiagnosticService(workspace);
                var provider = new DiagnosticsSquiggleTaggerProvider(
                    diagnosticService, workspace.GetService<IForegroundNotificationService>(), listeners);

                // Create and fire the diagnostic events before hte tagger is even made.
                var tree = await workspace.CurrentSolution.Projects.Single().Documents.Single().GetSyntaxTreeAsync();
                var span = TextSpan.FromBounds(0, 5);
                diagnosticService.CreateDiagnosticAndFireEvents(Location.Create(tree, span));

                var tagger = provider.CreateTagger<IErrorTag>(workspace.Documents.First().GetTextBuffer());
                using (var disposable = tagger as IDisposable)
                {
                    await asyncListener.CreateWaitTask();

                    var snapshot = workspace.Documents.First().GetTextBuffer().CurrentSnapshot;
                    var spans = tagger.GetTags(snapshot.GetSnapshotSpanCollection()).ToList();
                    Assert.Equal(1, spans.Count);
                    Assert.Equal(span.ToSpan(), spans[0].Span.Span);
                }
            }
        }