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)); }
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); } }
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); }
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); }
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)); }
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); }
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); }
/// <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)); }
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)); }
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 ); }
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); }
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)); }
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); } }
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) ); }
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}]")); }
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; } }
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()))); }
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)); }
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); }
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; } }
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)); }