예제 #1
0
        private static (TestWorkspace workspace, TestDiagnosticAnalyzerService analyzerService, CodeFixService codeFixService, IErrorLoggerService errorLogger) ServiceSetup(
            CodeFixProvider codefix,
            bool includeConfigurationFixProviders = false)
        {
            var fixers = SpecializedCollections.SingletonEnumerable(
                new Lazy <CodeFixProvider, CodeChangeProviderMetadata>(
                    () => codefix,
                    new CodeChangeProviderMetadata("Test", languages: LanguageNames.CSharp)));

            var code = @"class Program { }";

            var workspace         = TestWorkspace.CreateCSharp(code, openDocuments: true);
            var analyzerReference = new TestAnalyzerReferenceByLanguage(DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap());

            workspace.TryApplyChanges(workspace.CurrentSolution.WithAnalyzerReferences(new[] { analyzerReference }));

            var diagnosticService         = new TestDiagnosticAnalyzerService();
            var logger                    = SpecializedCollections.SingletonEnumerable(new Lazy <IErrorLoggerService>(() => new TestErrorLogger()));
            var errorLogger               = logger.First().Value;
            var configurationFixProviders = includeConfigurationFixProviders
                ? TestExportProvider.ExportProviderWithCSharpAndVisualBasic.GetExports <IConfigurationFixProvider, CodeChangeProviderMetadata>()
                : SpecializedCollections.EmptyEnumerable <Lazy <IConfigurationFixProvider, CodeChangeProviderMetadata> >();
            var fixService = new CodeFixService(
                workspace.ExportProvider.GetExportedValue <IThreadingContext>(),
                diagnosticService, logger, fixers, configurationFixProviders);

            return(workspace, diagnosticService, fixService, errorLogger);
        }
 private static DiagnosticAnalyzerService CreateDiagnosticAnalyzerService(
     Dictionary <string, DiagnosticAnalyzer[]> analyzerMap, IAsynchronousOperationListener listener)
 {
     return(analyzerMap == null || analyzerMap.Count == 0
         ? new MyDiagnosticAnalyzerService(DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap(), listener : listener)
            : new MyDiagnosticAnalyzerService(analyzerMap.ToImmutableDictionary(kvp => kvp.Key, kvp => kvp.Value.ToImmutableArray()), listener : listener));
 }
예제 #3
0
        public async Task TestGetFirstDiagnosticWithFixAsync()
        {
            var diagnosticService = new TestDiagnosticAnalyzerService(DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap());

            var fixers = CreateFixers();
            var code   = @"
    a
";

            using (var workspace = await TestWorkspace.CreateCSharpAsync(code))
            {
                var logger     = SpecializedCollections.SingletonEnumerable(new Lazy <IErrorLoggerService>(() => workspace.Services.GetService <IErrorLoggerService>()));
                var fixService = new CodeFixService(
                    diagnosticService, logger, fixers, SpecializedCollections.EmptyEnumerable <Lazy <ISuppressionFixProvider, CodeChangeProviderMetadata> >());

                var incrementalAnalyzer = (IIncrementalAnalyzerProvider)diagnosticService;

                // register diagnostic engine to solution crawler
                var analyzer = incrementalAnalyzer.CreateIncrementalAnalyzer(workspace);

                var reference = new MockAnalyzerReference();
                var project   = workspace.CurrentSolution.Projects.Single().AddAnalyzerReference(reference);
                var document  = project.Documents.Single();
                var unused    = await fixService.GetFirstDiagnosticWithFixAsync(document, TextSpan.FromBounds(0, 0), considerSuppressionFixes : false, cancellationToken : CancellationToken.None);

                var fixer1 = fixers.Single().Value as MockFixer;
                var fixer2 = reference.Fixer as MockFixer;

                // check to make sure both of them are called.
                Assert.True(fixer1.Called);
                Assert.True(fixer2.Called);
            }
        }
예제 #4
0
        private protected async Task TestDiagnosticsAsync(
            string initialMarkup, TestParameters?parameters = null, params DiagnosticDescription[] expected)
        {
            var ps = parameters ?? TestParameters.Default;

            using var workspace = CreateWorkspaceFromOptions(initialMarkup, ps);

            var diagnostics = await GetDiagnosticsAsync(workspace, ps).ConfigureAwait(false);

            // Special case for single diagnostic reported with annotated span.
            if (expected.Length == 1 && !expected[0].HasLocation)
            {
                var hostDocumentsWithAnnotations = workspace.Documents.Where(d => d.SelectedSpans.Any());
                if (hostDocumentsWithAnnotations.Count() == 1)
                {
                    var expectedSpan = hostDocumentsWithAnnotations.Single().SelectedSpans.Single();

                    Assert.Equal(1, diagnostics.Count());
                    var diagnostic = diagnostics.Single();

                    var actualSpan = diagnostic.Location.SourceSpan;
                    Assert.Equal(expectedSpan, actualSpan);

                    Assert.Equal(expected[0].Code, diagnostic.Id);
                    return;
                }
            }

            DiagnosticExtensions.Verify(diagnostics, expected);
        }
예제 #5
0
        private static (TestWorkspace workspace, DiagnosticAnalyzerService analyzerService, CodeFixService codeFixService, IErrorLoggerService errorLogger) ServiceSetup(
            CodeFixProvider codefix,
            bool includeConfigurationFixProviders = false,
            bool throwExceptionInFixerCreation    = false)
        {
            var fixers = SpecializedCollections.SingletonEnumerable(
                new Lazy <CodeFixProvider, CodeChangeProviderMetadata>(
                    () => throwExceptionInFixerCreation ? throw new Exception() : codefix,
                    new CodeChangeProviderMetadata("Test", languages: LanguageNames.CSharp)));

            var code = @"class Program { }";

            var workspace         = TestWorkspace.CreateCSharp(code, composition: s_compositionWithMockDiagnosticUpdateSourceRegistrationService, openDocuments: true);
            var analyzerReference = new TestAnalyzerReferenceByLanguage(DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap());

            workspace.TryApplyChanges(workspace.CurrentSolution.WithAnalyzerReferences(new[] { analyzerReference }));

            Assert.IsType <MockDiagnosticUpdateSourceRegistrationService>(workspace.GetService <IDiagnosticUpdateSourceRegistrationService>());
            var diagnosticService = Assert.IsType <DiagnosticAnalyzerService>(workspace.GetService <IDiagnosticAnalyzerService>());
            var logger            = SpecializedCollections.SingletonEnumerable(new Lazy <IErrorLoggerService>(() => new TestErrorLogger()));
            var errorLogger       = logger.First().Value;

            var configurationFixProviders = includeConfigurationFixProviders
                ? workspace.ExportProvider.GetExports <IConfigurationFixProvider, CodeChangeProviderMetadata>()
                : SpecializedCollections.EmptyEnumerable <Lazy <IConfigurationFixProvider, CodeChangeProviderMetadata> >();

            var fixService = new CodeFixService(
                workspace.ExportProvider.GetExportedValue <IThreadingContext>(),
                diagnosticService,
                logger,
                fixers,
                configurationFixProviders);

            return(workspace, diagnosticService, fixService, errorLogger);
        }
예제 #6
0
        private async Task <ImmutableArray <CodeFixCollection> > GetNuGetAndVsixCodeFixersCoreAsync(
            NuGetCodeFixProvider?nugetFixer,
            VsixCodeFixProvider?vsixFixer,
            MockAnalyzerReference.MockDiagnosticAnalyzer?diagnosticAnalyzer = null)
        {
            var code = @"class C { }";
            var diagnosticService = new TestDiagnosticAnalyzerService(DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap());

            var vsixFixers = vsixFixer != null
                ? SpecializedCollections.SingletonEnumerable(new Lazy <CodeFixProvider, CodeChangeProviderMetadata>(() => vsixFixer, new CodeChangeProviderMetadata(name: nameof(VsixCodeFixProvider), languages: LanguageNames.CSharp)))
                : SpecializedCollections.EmptyEnumerable <Lazy <CodeFixProvider, CodeChangeProviderMetadata> >();

            using var workspace = TestWorkspace.CreateCSharp(code, openDocuments: true);

            var logger     = SpecializedCollections.SingletonEnumerable(new Lazy <IErrorLoggerService>(() => workspace.Services.GetRequiredService <IErrorLoggerService>()));
            var fixService = new CodeFixService(
                workspace.ExportProvider.GetExportedValue <IThreadingContext>(),
                diagnosticService, logger, vsixFixers, SpecializedCollections.EmptyEnumerable <Lazy <IConfigurationFixProvider, CodeChangeProviderMetadata> >());

            var incrementalAnalyzer = (IIncrementalAnalyzerProvider)diagnosticService;

            // register diagnostic engine to solution crawler
            var analyzer = incrementalAnalyzer.CreateIncrementalAnalyzer(workspace);

            diagnosticAnalyzer ??= new MockAnalyzerReference.MockDiagnosticAnalyzer();
            var analyzers = ImmutableArray.Create <DiagnosticAnalyzer>(diagnosticAnalyzer);
            var reference = new MockAnalyzerReference(nugetFixer, analyzers);
            var project   = workspace.CurrentSolution.Projects.Single().AddAnalyzerReference(reference);

            var document = project.Documents.Single();

            return(await fixService.GetFixesAsync(document, TextSpan.FromBounds(0, 0), includeConfigurationFixes : false, cancellationToken : CancellationToken.None));
        }
예제 #7
0
        public async Task TestGetFirstDiagnosticWithFixAsync()
        {
            var diagnosticService = new TestDiagnosticAnalyzerService(DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap());

            var fixers = CreateFixers();
            var code   = @"
    a
";

            using var workspace = TestWorkspace.CreateCSharp(code, openDocuments: true);

            var logger     = SpecializedCollections.SingletonEnumerable(new Lazy <IErrorLoggerService>(() => workspace.Services.GetRequiredService <IErrorLoggerService>()));
            var fixService = new CodeFixService(
                workspace.ExportProvider.GetExportedValue <IThreadingContext>(),
                diagnosticService, logger, fixers, SpecializedCollections.EmptyEnumerable <Lazy <IConfigurationFixProvider, CodeChangeProviderMetadata> >());

            var incrementalAnalyzer = (IIncrementalAnalyzerProvider)diagnosticService;

            // register diagnostic engine to solution crawler
            var analyzer = incrementalAnalyzer.CreateIncrementalAnalyzer(workspace);

            var reference = new MockAnalyzerReference();
            var project   = workspace.CurrentSolution.Projects.Single().AddAnalyzerReference(reference);
            var document  = project.Documents.Single();
            var unused    = await fixService.GetMostSevereFixableDiagnosticAsync(document, TextSpan.FromBounds(0, 0), cancellationToken : CancellationToken.None);

            var fixer1 = (MockFixer)fixers.Single().Value;
            var fixer2 = (MockFixer)reference.Fixer !;

            // check to make sure both of them are called.
            Assert.True(fixer1.Called);
            Assert.True(fixer2.Called);
        }
예제 #8
0
        public void TestPreviewDiagnostic()
        {
            var diagnosticService = EditorServicesUtil.ExportProvider.GetExportedValue <IDiagnosticAnalyzerService>() as IDiagnosticUpdateSource;

            RoslynDebug.AssertNotNull(diagnosticService);

            var taskSource = new TaskCompletionSource <DiagnosticsUpdatedArgs>();

            diagnosticService.DiagnosticsUpdated += (s, a) => taskSource.TrySetResult(a);

            using var previewWorkspace = new PreviewWorkspace(VisualStudioMefHostServices.Create(EditorServicesUtil.ExportProvider));

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

            previewWorkspace.OpenDocument(previewWorkspace.CurrentSolution.Projects.First().DocumentIds[0]);
            previewWorkspace.EnableDiagnostic();

            // wait 20 seconds
            taskSource.Task.Wait(20000);
            Assert.True(taskSource.Task.IsCompleted);

            var args = taskSource.Task.Result;

            Assert.True(args.Diagnostics.Length > 0);
        }
예제 #9
0
        /// <summary>
        /// Does the configure diagnostics.
        /// </summary>
        /// <param name="services">The services.</param>
        protected override void DoConfigureDiagnostics(IServiceCollection services)
        {
            DiagnosticExtensions.AddDiagnosisActions(NAFSettings.Current, new Assembly[] { Assembly.GetExecutingAssembly() });

            var settings = NAFSettings.Current.ReadAppSettings <SampleAppSettings>(throwIfNotFound: false) ?? new SampleAppSettings();

            services.AddSingleton <IDiagnosisService>(new GenericDiagnosisService(settings));
        }
예제 #10
0
        public DiagnosticTaggerWrapper(
            TestWorkspace workspace,
            IReadOnlyDictionary <string, ImmutableArray <DiagnosticAnalyzer> >?analyzerMap = null,
            IDiagnosticUpdateSource?updateSource = null,
            bool createTaggerProvider            = true
            )
        {
            _threadingContext = workspace.GetService <IThreadingContext>();
            _listenerProvider = workspace.GetService <IAsynchronousOperationListenerProvider>();

            var analyzerReference = new TestAnalyzerReferenceByLanguage(
                analyzerMap ?? DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap()
                );

            workspace.TryApplyChanges(
                workspace.CurrentSolution.WithAnalyzerReferences(new[] { analyzerReference })
                );

            _workspace = workspace;

            _registrationService =
                (SolutionCrawlerRegistrationService)workspace.Services.GetRequiredService <ISolutionCrawlerRegistrationService>();
            _registrationService.Register(workspace);

            if (
                !_registrationService
                .GetTestAccessor()
                .TryGetWorkCoordinator(workspace, out var coordinator)
                )
            {
                throw new InvalidOperationException();
            }

            AnalyzerService = (DiagnosticAnalyzerService?)_registrationService
                              .GetTestAccessor()
                              .AnalyzerProviders.SelectMany(pair => pair.Value)
                              .SingleOrDefault(
                lazyProvider =>
                lazyProvider.Metadata.Name == WellKnownSolutionCrawlerAnalyzers.Diagnostic &&
                lazyProvider.Metadata.HighPriorityForActiveFile
                )
                              ?.Value;
            DiagnosticService =
                (DiagnosticService)workspace.ExportProvider.GetExportedValue <IDiagnosticService>();

            if (updateSource is object)
            {
                DiagnosticService.Register(updateSource);
            }

            if (createTaggerProvider)
            {
                _ = TaggerProvider;
            }
        }
        private static IEnumerable <string> GetCompilerAnalyzerAssemblies()
        {
            var compilerAnalyzersMap = DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap();

            foreach (var analyzers in compilerAnalyzersMap.Values)
            {
                foreach (var analyzer in analyzers)
                {
                    yield return(analyzer.GetType().Assembly.Location);
                }
            }
        }
        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);
        }
        private TestDiagnosticAnalyzerService CreateDiagnosticAnalyzerService(Project project, DiagnosticAnalyzer workspaceAnalyzerOpt)
        {
            if (workspaceAnalyzerOpt != null)
            {
                return(new TestDiagnosticAnalyzerService(project.Language, workspaceAnalyzerOpt, _exceptionDiagnosticsSource));
            }

            var analyzer           = DiagnosticExtensions.GetCompilerDiagnosticAnalyzer(project.Language);
            var analyzerService    = project.Solution.Workspace.Services.GetService <IAnalyzerService>();
            var analyzerReferences = ImmutableArray.Create <AnalyzerReference>(new AnalyzerFileReference(analyzer.GetType().Assembly.Location, analyzerService.GetLoader()));

            return(new TestDiagnosticAnalyzerService(analyzerReferences, _exceptionDiagnosticsSource));
        }
예제 #14
0
        public async Task TestPreviewDiagnostic()
        {
            var hostServices = EditorTestCompositions.EditorFeatures.GetHostServices();

            var diagnosticService = (IDiagnosticUpdateSource)(
                (IMefHostExportProvider)hostServices
                ).GetExportedValue <IDiagnosticAnalyzerService>();

            RoslynDebug.AssertNotNull(diagnosticService);

            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.EnableDiagnostic();

            // wait 20 seconds
            taskSource.Task.Wait(20000);
            Assert.True(taskSource.Task.IsCompleted);

            var args = taskSource.Task.Result;

            Assert.True(
                args.GetPushDiagnostics(
                    previewWorkspace,
                    InternalDiagnosticsOptions.NormalDiagnosticMode
                    ).Length > 0
                );
        }
예제 #15
0
        private static TestWorkspace ServiceSetup(CodeFixProvider codefix, out TestDiagnosticAnalyzerService diagnosticService, out CodeFixService fixService, out IErrorLoggerService errorLogger)
        {
            diagnosticService = new TestDiagnosticAnalyzerService(DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap());
            var fixers = SpecializedCollections.SingletonEnumerable(
                new Lazy <CodeFixProvider, CodeChangeProviderMetadata>(
                    () => codefix,
                    new CodeChangeProviderMetadata("Test", languages: LanguageNames.CSharp)));
            var code      = @"class Program { }";
            var workspace = CSharpWorkspaceFactory.CreateWorkspaceFromFile(code);
            var logger    = SpecializedCollections.SingletonEnumerable(new Lazy <IErrorLoggerService>(() => new TestErrorLogger()));

            errorLogger = logger.First().Value;
            fixService  = new CodeFixService(
                diagnosticService, logger, fixers, SpecializedCollections.EmptyEnumerable <Lazy <ISuppressionFixProvider, CodeChangeProviderMetadata> >());
            return(workspace);
        }
예제 #16
0
        private static Tuple <TestWorkspace, TestDiagnosticAnalyzerService, CodeFixService, IErrorLoggerService> ServiceSetup(CodeFixProvider codefix)
        {
            var diagnosticService = new TestDiagnosticAnalyzerService(DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap());
            var fixers            = SpecializedCollections.SingletonEnumerable(
                new Lazy <CodeFixProvider, CodeChangeProviderMetadata>(
                    () => codefix,
                    new CodeChangeProviderMetadata("Test", languages: LanguageNames.CSharp)));
            var code        = @"class Program { }";
            var workspace   = TestWorkspace.CreateCSharp(code);
            var logger      = SpecializedCollections.SingletonEnumerable(new Lazy <IErrorLoggerService>(() => new TestErrorLogger()));
            var errorLogger = logger.First().Value;
            var fixService  = new CodeFixService(
                workspace.ExportProvider.GetExportedValue <IThreadingContext>(),
                diagnosticService, logger, fixers, SpecializedCollections.EmptyEnumerable <Lazy <IConfigurationFixProvider, CodeChangeProviderMetadata> >());

            return(Tuple.Create(workspace, diagnosticService, fixService, errorLogger));
        }
예제 #17
0
        public async Task TestCodeActionHasCorrectDiagnostics()
        {
            var markup =
                @"class A
{
    void M()
    {
        {|caret:|}Task.Delay(1);
    }
}";

            using var testLspServer = await CreateTestLspServerAsync(markup);

            testLspServer.InitializeDiagnostics(BackgroundAnalysisScope.ActiveFile, DiagnosticMode.Default,
                                                new TestAnalyzerReferenceByLanguage(DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap()));
            await testLspServer.WaitForDiagnosticsAsync();

            var caret            = testLspServer.GetLocations("caret").Single();
            var codeActionParams = new LSP.CodeActionParams
            {
                TextDocument = CreateTextDocumentIdentifier(caret.Uri),
                Range        = caret.Range,
                Context      = new LSP.CodeActionContext
                {
                    Diagnostics = new[]
                    {
                        new LSP.Diagnostic
                        {
                            Code = AddImportDiagnosticIds.CS0103
                        },
                        new LSP.Diagnostic
                        {
                            Code = "SomeCode"
                        }
                    }
                }
            };

            var results = await RunGetCodeActionsAsync(testLspServer, codeActionParams);

            var addImport = results.FirstOrDefault(r => r.Title.Contains($"using System.Threading.Tasks"));

            Assert.Equal(1, addImport.Diagnostics.Length);
            Assert.Equal(AddImportDiagnosticIds.CS0103, addImport.Diagnostics.Single().Code.Value);
        }
        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);
            }
        }
예제 #19
0
        protected static void AddAnalyzerToWorkspace(
            Workspace workspace,
            DiagnosticAnalyzer analyzer,
            TestParameters parameters
            )
        {
            AnalyzerReference[] analyzeReferences;
            if (analyzer != null)
            {
                Contract.ThrowIfTrue(
                    parameters.testHost == TestHost.OutOfProcess,
                    $"Out-of-proc testing is not supported since {analyzer} can't be serialized."
                    );

                analyzeReferences = new[]
                {
                    new AnalyzerImageReference(ImmutableArray.Create(analyzer))
                };
            }
            else
            {
                // create a serializable analyzer reference:
                analyzeReferences = new[]
                {
                    new AnalyzerFileReference(
                        DiagnosticExtensions
                        .GetCompilerDiagnosticAnalyzer(LanguageNames.CSharp)
                        .GetType().Assembly.Location,
                        TestAnalyzerAssemblyLoader.LoadFromFile
                        ),
                    new AnalyzerFileReference(
                        DiagnosticExtensions
                        .GetCompilerDiagnosticAnalyzer(LanguageNames.VisualBasic)
                        .GetType().Assembly.Location,
                        TestAnalyzerAssemblyLoader.LoadFromFile
                        )
                };
            }

            workspace.TryApplyChanges(
                workspace.CurrentSolution.WithAnalyzerReferences(analyzeReferences)
                );
        }
예제 #20
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.EnableDiagnostic();

            var diagnosticsAndErrorsSpans =
                await SquiggleUtilities.GetDiagnosticsAndErrorSpansAsync <DiagnosticsSquiggleTaggerProvider>(
                    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
                );
        }
        public void References_Versioning_WeakNames3()
        {
            var c1 = Temp.CreateFile(extension: ".dll").WriteAllBytes(
                CreateCSharpCompilation(@"[assembly: System.Reflection.AssemblyVersion(""1.0.0.0"")] public class C {}", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, assemblyName: "C").EmitToArray());

            var c2 = Temp.CreateFile(extension: ".dll").WriteAllBytes(
                CreateCSharpCompilation(@"[assembly: System.Reflection.AssemblyVersion(""2.0.0.0"")] public class C {}", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, assemblyName: "C").EmitToArray());

            var script0 = CSharpScript.Create($@"
#r ""{c1.Path}""
var c1 = new C();
");

            script0.GetCompilation().VerifyAssemblyVersionsAndAliases(
                "C, Version=1.0.0.0",
                "mscorlib, Version=4.0.0.0");

            var script1 = script0.ContinueWith($@"
#r ""{c2.Path}""
var c2 = new C();
");

            script1.GetCompilation().VerifyAssemblyVersionsAndAliases(
                "C, Version=2.0.0.0",
                "C, Version=1.0.0.0: <superseded>",
                "mscorlib, Version=4.0.0.0");

            var script2 = script1.ContinueWith(@"
c1 = c2;
");

            script2.GetCompilation().VerifyAssemblyVersionsAndAliases(
                "C, Version=2.0.0.0",
                "C, Version=1.0.0.0: <superseded>",
                "mscorlib, Version=4.0.0.0");

            DiagnosticExtensions.VerifyEmitDiagnostics(script2.GetCompilation(),
                                                       // (2,6): error CS0029: Cannot implicitly convert type 'C [{c2.Path}]' to 'C [{c1.Path}]'
                                                       Diagnostic(ErrorCode.ERR_NoImplicitConv, "c2").WithArguments($"C [{c2.Path}]", $"C [{c1.Path}]"));
        }
예제 #22
0
        public async Task TestGetFirstDiagnosticWithFixAsync()
        {
            var fixers = CreateFixers();
            var code   = @"
    a
";

            using var workspace = TestWorkspace.CreateCSharp(code, composition: s_compositionWithMockDiagnosticUpdateSourceRegistrationService, openDocuments: true);

            Assert.IsType <MockDiagnosticUpdateSourceRegistrationService>(workspace.GetService <IDiagnosticUpdateSourceRegistrationService>());
            var diagnosticService = Assert.IsType <DiagnosticAnalyzerService>(workspace.GetService <IDiagnosticAnalyzerService>());

            var analyzerReference = new TestAnalyzerReferenceByLanguage(DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap());

            workspace.TryApplyChanges(workspace.CurrentSolution.WithAnalyzerReferences(new[] { analyzerReference }));

            var logger     = SpecializedCollections.SingletonEnumerable(new Lazy <IErrorLoggerService>(() => workspace.Services.GetRequiredService <IErrorLoggerService>()));
            var fixService = new CodeFixService(
                diagnosticService, logger, fixers, SpecializedCollections.EmptyEnumerable <Lazy <IConfigurationFixProvider, CodeChangeProviderMetadata> >());

            var incrementalAnalyzer = (IIncrementalAnalyzerProvider)diagnosticService;

            // register diagnostic engine to solution crawler
            var analyzer = incrementalAnalyzer.CreateIncrementalAnalyzer(workspace);

            var reference = new MockAnalyzerReference();
            var project   = workspace.CurrentSolution.Projects.Single().AddAnalyzerReference(reference);
            var document  = project.Documents.Single();
            var unused    = await fixService.GetMostSevereFixAsync(
                document, TextSpan.FromBounds(0, 0), CodeActionRequestPriority.None, CodeActionOptions.DefaultProvider, isBlocking : false, CancellationToken.None);

            var fixer1 = (MockFixer)fixers.Single().Value;
            var fixer2 = (MockFixer)reference.Fixer !;

            // check to make sure both of them are called.
            Assert.True(fixer1.Called);
            Assert.True(fixer2.Called);
        }
        private static IEnumerable <Diagnostic> GetDiagnostics(DiagnosticAnalyzer workspaceAnalyzerOpt, Document document, TextSpan span, Project project, bool getDocumentDiagnostics, bool getProjectDiagnostics, Action <Exception, DiagnosticAnalyzer, Diagnostic> onAnalyzerException, bool logAnalyzerExceptionAsDiagnostics)
        {
            var documentDiagnostics = SpecializedCollections.EmptyEnumerable <Diagnostic>();
            var projectDiagnostics  = SpecializedCollections.EmptyEnumerable <Diagnostic>();

            // If no user diagnostic analyzer, then test compiler diagnostics.
            var workspaceAnalyzer = workspaceAnalyzerOpt ?? DiagnosticExtensions.GetCompilerDiagnosticAnalyzer(project.Language);

            // If the test is not configured with a custom onAnalyzerException handler AND has not requested exceptions to be handled and logged as diagnostics, then FailFast on exceptions.
            if (onAnalyzerException == null && !logAnalyzerExceptionAsDiagnostics)
            {
                onAnalyzerException = DiagnosticExtensions.FailFastOnAnalyzerException;
            }

            var exceptionDiagnosticsSource = new TestHostDiagnosticUpdateSource(project.Solution.Workspace);
            var analyzerService            = new TestDiagnosticAnalyzerService(project.Language, workspaceAnalyzer, exceptionDiagnosticsSource, onAnalyzerException);
            var incrementalAnalyzer        = analyzerService.CreateIncrementalAnalyzer(project.Solution.Workspace);

            if (getDocumentDiagnostics)
            {
                var tree = document.GetSyntaxTreeAsync().Result;
                var root = tree.GetRoot();
                var dxs  = analyzerService.GetDiagnosticsAsync(project.Solution, project.Id, document.Id).WaitAndGetResult(CancellationToken.None);
                documentDiagnostics = dxs.Where(d => d.HasTextSpan && d.TextSpan.IntersectsWith(span)).Select(d => d.ToDiagnostic(tree));
            }

            if (getProjectDiagnostics)
            {
                var dxs = analyzerService.GetDiagnosticsAsync(project.Solution, project.Id).WaitAndGetResult(CancellationToken.None);
                projectDiagnostics = dxs.Where(d => !d.HasTextSpan).Select(d => d.ToDiagnostic(tree: null));
            }

            var exceptionDiagnostics = exceptionDiagnosticsSource.TestOnly_GetReportedDiagnostics(workspaceAnalyzer).Select(d => d.ToDiagnostic(tree: null));

            return(documentDiagnostics.Concat(projectDiagnostics).Concat(exceptionDiagnostics));
        }
        public DiagnosticTaggerWrapper(
            TestWorkspace workspace,
            IReadOnlyDictionary <string, ImmutableArray <DiagnosticAnalyzer> >?analyzerMap = null,
            IDiagnosticUpdateSource?updateSource = null,
            bool createTaggerProvider            = true)
        {
            _threadingContext = workspace.GetService <IThreadingContext>();
            _listenerProvider = workspace.GetService <IAsynchronousOperationListenerProvider>();

            var analyzerReference = new TestAnalyzerReferenceByLanguage(analyzerMap ?? DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap());

            workspace.TryApplyChanges(workspace.CurrentSolution.WithAnalyzerReferences(new[] { analyzerReference }));

            // Change the background analysis scope to OpenFiles instead of ActiveFile (default),
            // so that every diagnostic tagger test does not need to mark test files as "active" file.
            workspace.GlobalOptions.SetGlobalOption(new OptionKey(SolutionCrawlerOptionsStorage.BackgroundAnalysisScopeOption, LanguageNames.CSharp), BackgroundAnalysisScope.OpenFiles);
            workspace.GlobalOptions.SetGlobalOption(new OptionKey(SolutionCrawlerOptionsStorage.BackgroundAnalysisScopeOption, LanguageNames.VisualBasic), BackgroundAnalysisScope.OpenFiles);

            _workspace = workspace;

            _registrationService = (SolutionCrawlerRegistrationService)workspace.Services.GetRequiredService <ISolutionCrawlerRegistrationService>();
            _registrationService.Register(workspace);

            if (!_registrationService.GetTestAccessor().TryGetWorkCoordinator(workspace, out var coordinator))
            {
                throw new InvalidOperationException();
            }

            AnalyzerService   = (DiagnosticAnalyzerService?)_registrationService.GetTestAccessor().AnalyzerProviders.SelectMany(pair => pair.Value).SingleOrDefault(lazyProvider => lazyProvider.Metadata.Name == WellKnownSolutionCrawlerAnalyzers.Diagnostic && lazyProvider.Metadata.HighPriorityForActiveFile)?.Value;
            DiagnosticService = (DiagnosticService)workspace.ExportProvider.GetExportedValue <IDiagnosticService>();

            if (updateSource is object)
            {
                DiagnosticService.Register(updateSource);
            }

            if (createTaggerProvider)
            {
                _ = TaggerProvider;
            }
        }
예제 #25
0
 public TestDiagnosticAnalyzerDriver(Project project, DiagnosticAnalyzer workspaceAnalyzerOpt = null, Action <Exception, DiagnosticAnalyzer, Diagnostic> onAnalyzerException = null, bool logAnalyzerExceptionAsDiagnostics = false, bool includeSuppressedDiagnostics = false)
     : this(project, ImmutableArray.Create(workspaceAnalyzerOpt ?? DiagnosticExtensions.GetCompilerDiagnosticAnalyzer(project.Language)), onAnalyzerException, logAnalyzerExceptionAsDiagnostics, includeSuppressedDiagnostics)
 {
 }
 private static DiagnosticAnalyzerService CreateDiagnosticAnalyzerService(Dictionary <string, DiagnosticAnalyzer[]> analyzerMap)
 {
     return(analyzerMap == null || analyzerMap.Count == 0
         ? new TestDiagnosticAnalyzerService(DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap())
            : new TestDiagnosticAnalyzerService(analyzerMap.ToImmutableDictionary(kvp => kvp.Key, kvp => kvp.Value.ToImmutableArray())));
 }
예제 #27
0
        private static IEnumerable <Diagnostic> GetDiagnostics(DiagnosticAnalyzer analyzerOpt, Document document, TextSpan span, Project project, bool getDocumentDiagnostics, bool getProjectDiagnostics, Action <Exception, DiagnosticAnalyzer, Diagnostic> onAnalyzerException, bool logAnalyzerExceptionAsDiagnostics)
        {
            var documentDiagnostics = SpecializedCollections.EmptyEnumerable <Diagnostic>();
            var projectDiagnostics  = SpecializedCollections.EmptyEnumerable <Diagnostic>();

            // If no user diagnostic analyzer, then test compiler diagnostics.
            var analyzer = analyzerOpt ?? DiagnosticExtensions.GetCompilerDiagnosticAnalyzer(project.Language);

            // If the test is not configured with a custom onAnalyzerException handler AND has not requested exceptions to be handled and logged as diagnostics, then FailFast on exceptions.
            if (onAnalyzerException == null && !logAnalyzerExceptionAsDiagnostics)
            {
                onAnalyzerException = DiagnosticExtensions.FailFastOnAnalyzerException;
            }

            var exceptionDiagnosticsSource = new TestHostDiagnosticUpdateSource(project.Solution.Workspace);

            if (getDocumentDiagnostics)
            {
                var tree          = document.GetSyntaxTreeAsync().Result;
                var root          = document.GetSyntaxRootAsync().Result;
                var semanticModel = document.GetSemanticModelAsync().Result;

                var builder = new List <Diagnostic>();
                var nodeInBodyAnalyzerService = document.Project.Language == LanguageNames.CSharp ?
                                                (ISyntaxNodeAnalyzerService) new CSharpSyntaxNodeAnalyzerService() :
                                                new VisualBasicSyntaxNodeAnalyzerService();

                // Lets replicate the IDE diagnostic incremental analyzer behavior to determine span to test:
                //  (a) If the span is contained within a method level member and analyzer supports semantic in span: analyze in member span.
                //  (b) Otherwise, analyze entire syntax tree span.
                var spanToTest = root.FullSpan;

                var driver = new DiagnosticAnalyzerDriver(document, spanToTest, root,
                                                          syntaxNodeAnalyzerService: nodeInBodyAnalyzerService,
                                                          hostDiagnosticUpdateSource: exceptionDiagnosticsSource,
                                                          overriddenOnAnalyzerException: onAnalyzerException);
                var  diagnosticAnalyzerCategory = analyzer.GetDiagnosticAnalyzerCategory(driver);
                bool supportsSemanticInSpan     = (diagnosticAnalyzerCategory & DiagnosticAnalyzerCategory.SemanticSpanAnalysis) != 0;
                if (supportsSemanticInSpan)
                {
                    var syntaxFacts = document.Project.LanguageServices.GetService <ISyntaxFactsService>();
                    if (syntaxFacts != null)
                    {
                        var member = syntaxFacts.GetContainingMemberDeclaration(root, span.Start);
                        if (member != null && syntaxFacts.IsMethodLevelMember(member) && member.FullSpan.Contains(span))
                        {
                            spanToTest = member.FullSpan;
                        }
                    }
                }

                if ((diagnosticAnalyzerCategory & DiagnosticAnalyzerCategory.SyntaxAnalysis) != 0)
                {
                    builder.AddRange(driver.GetSyntaxDiagnosticsAsync(analyzer).Result);
                }

                if (supportsSemanticInSpan || (diagnosticAnalyzerCategory & DiagnosticAnalyzerCategory.SemanticDocumentAnalysis) != 0)
                {
                    builder.AddRange(driver.GetSemanticDiagnosticsAsync(analyzer).Result);
                }

                documentDiagnostics = builder.Where(d => d.Location == Location.None ||
                                                    (d.Location.SourceTree == tree && d.Location.SourceSpan.IntersectsWith(span)));
            }

            if (getProjectDiagnostics)
            {
                var nodeInBodyAnalyzerService = project.Language == LanguageNames.CSharp ?
                                                (ISyntaxNodeAnalyzerService) new CSharpSyntaxNodeAnalyzerService() :
                                                new VisualBasicSyntaxNodeAnalyzerService();
                var driver = new DiagnosticAnalyzerDriver(project, nodeInBodyAnalyzerService, exceptionDiagnosticsSource, overriddenOnAnalyzerException: onAnalyzerException);

                if (analyzer.SupportsProjectDiagnosticAnalysis(driver))
                {
                    projectDiagnostics = driver.GetProjectDiagnosticsAsync(analyzer, null).Result;
                }
            }

            var exceptionDiagnostics = exceptionDiagnosticsSource.TestOnly_GetReportedDiagnostics(analyzer).Select(d => d.ToDiagnostic(tree: null));

            return(documentDiagnostics.Concat(projectDiagnostics).Concat(exceptionDiagnostics));
        }
예제 #28
0
        public async Task TestPreviewDiagnosticTaggerInPreviewPane()
        {
            // TODO: WPF required due to https://github.com/dotnet/roslyn/issues/46153
            using var workspace = TestWorkspace.CreateCSharp("class { }", composition: EditorTestCompositions.EditorFeaturesWpf);

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

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

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

            // make a change to remove squiggle
            var oldDocument = workspace.CurrentSolution.GetRequiredDocument(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);

            AssertEx.NotNull(diffView);

            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 provider   = workspace.ExportProvider.GetExportedValues <ITaggerProvider>().OfType <DiagnosticsSquiggleTaggerProvider>().Single();
            var leftTagger = provider.CreateTagger <IErrorTag>(leftBuffer);

            using var leftDisposable = leftTagger as IDisposable;
            var rightBuffer = diffView.Viewer.RightView.BufferGraph.GetTextBuffers(t => t.ContentType.IsOfType(ContentTypeNames.CSharpContentType)).First();
            var rightTagger = provider.CreateTagger <IErrorTag>(rightBuffer);

            using var rightDisposable = rightTagger as IDisposable;
            // wait for diagnostics and taggers
            await listenerProvider.WaitAllDispatcherOperationAndTasksAsync(workspace, 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);
        }
예제 #29
0
        public DiagnosticTaggerWrapper(
            TestWorkspace workspace,
            IReadOnlyDictionary <string, ImmutableArray <DiagnosticAnalyzer> >?analyzerMap = null,
            IDiagnosticUpdateSource?updateSource = null,
            bool createTaggerProvider            = true)
        {
            _threadingContext = workspace.GetService <IThreadingContext>();
            _listenerProvider = workspace.GetService <IAsynchronousOperationListenerProvider>();

            if (updateSource == null)
            {
                updateSource = AnalyzerService = new MyDiagnosticAnalyzerService(_listenerProvider.GetListener(FeatureAttribute.DiagnosticService));
            }

            var analyzerReference = new TestAnalyzerReferenceByLanguage(analyzerMap ?? DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap());

            workspace.TryApplyChanges(workspace.CurrentSolution.WithAnalyzerReferences(new[] { analyzerReference }));

            _workspace = workspace;

            _registrationService = workspace.Services.GetRequiredService <ISolutionCrawlerRegistrationService>();
            _registrationService.Register(workspace);

            DiagnosticService = new DiagnosticService(_listenerProvider, Array.Empty <Lazy <IEventListener, EventListenerMetadata> >());
            DiagnosticService.Register(updateSource);

            if (createTaggerProvider)
            {
                _ = TaggerProvider;
            }

            if (AnalyzerService != null)
            {
                _incrementalAnalyzers   = ImmutableArray.Create(AnalyzerService.CreateIncrementalAnalyzer(workspace));
                _solutionCrawlerService = workspace.Services.GetService <ISolutionCrawlerRegistrationService>() as SolutionCrawlerRegistrationService;
            }
        }
예제 #30
0
        private static IEnumerable <Diagnostic> GetDiagnostics(DiagnosticAnalyzer analyzerOpt, Document document, TextSpan span, Project project, bool getDocumentDiagnostics, bool getProjectDiagnostics, bool donotCatchAnalyzerExceptions)
        {
            var documentDiagnostics = SpecializedCollections.EmptyEnumerable <Diagnostic>();
            var projectDiagnostics  = SpecializedCollections.EmptyEnumerable <Diagnostic>();

            // If no user diagnostic analyzer, then test compiler diagnostics.
            var analyzer = analyzerOpt ?? DiagnosticExtensions.GetCompilerDiagnosticAnalyzer(project.Language);

            if (getDocumentDiagnostics)
            {
                var tree          = document.GetSyntaxTreeAsync().Result;
                var root          = document.GetSyntaxRootAsync().Result;
                var semanticModel = document.GetSemanticModelAsync().Result;

                var builder = new List <Diagnostic>();
                var nodeInBodyAnalyzerService = document.Project.Language == LanguageNames.CSharp ?
                                                (ISyntaxNodeAnalyzerService) new CSharpSyntaxNodeAnalyzerService() :
                                                new VisualBasicSyntaxNodeAnalyzerService();

                // Lets replicate the IDE diagnostic incremental analyzer behavior to determine span to test:
                //  (a) If the span is contained within a method level member and analyzer supports semantic in span: analyze in member span.
                //  (b) Otherwise, analyze entire syntax tree span.
                var spanToTest = root.FullSpan;

                var  driver = new DiagnosticAnalyzerDriver(document, spanToTest, root, syntaxNodeAnalyzerService: nodeInBodyAnalyzerService, cancellationToken: CancellationToken.None, testOnly_DonotCatchAnalyzerExceptions: donotCatchAnalyzerExceptions);
                var  diagnosticAnalyzerCategory = analyzer.GetDiagnosticAnalyzerCategory(driver);
                bool supportsSemanticInSpan     = (diagnosticAnalyzerCategory & DiagnosticAnalyzerCategory.SemanticSpanAnalysis) != 0;
                if (supportsSemanticInSpan)
                {
                    var syntaxFacts = document.Project.LanguageServices.GetService <ISyntaxFactsService>();
                    if (syntaxFacts != null)
                    {
                        var member = syntaxFacts.GetContainingMemberDeclaration(root, span.Start);
                        if (member != null && syntaxFacts.IsMethodLevelMember(member) && member.FullSpan.Contains(span))
                        {
                            spanToTest = member.FullSpan;
                        }
                    }
                }

                if ((diagnosticAnalyzerCategory & DiagnosticAnalyzerCategory.SyntaxAnalysis) != 0)
                {
                    builder.AddRange(driver.GetSyntaxDiagnosticsAsync(analyzer).Result ?? SpecializedCollections.EmptyEnumerable <Diagnostic>());
                }

                if (supportsSemanticInSpan || (diagnosticAnalyzerCategory & DiagnosticAnalyzerCategory.SemanticDocumentAnalysis) != 0)
                {
                    builder.AddRange(driver.GetSemanticDiagnosticsAsync(analyzer).Result ?? SpecializedCollections.EmptyEnumerable <Diagnostic>());
                }

                documentDiagnostics = builder.Where(d => d.Location == Location.None ||
                                                    (d.Location.SourceTree == tree && d.Location.SourceSpan.IntersectsWith(span)));
            }

            if (getProjectDiagnostics)
            {
                var nodeInBodyAnalyzerService = project.Language == LanguageNames.CSharp ?
                                                (ISyntaxNodeAnalyzerService) new CSharpSyntaxNodeAnalyzerService() :
                                                new VisualBasicSyntaxNodeAnalyzerService();
                var driver = new DiagnosticAnalyzerDriver(project, nodeInBodyAnalyzerService, CancellationToken.None);

                if (analyzer.SupportsProjectDiagnosticAnalysis(driver))
                {
                    projectDiagnostics = driver.GetProjectDiagnosticsAsync(analyzer, null).Result ?? SpecializedCollections.EmptyEnumerable <Diagnostic>();
                }
            }

            return(documentDiagnostics.Concat(projectDiagnostics));
        }