File: Diagnostics\DefaultDiagnosticUpdateSourceTests.vb
Web Access
Project: ..\..\..\src\VisualStudio\Core\Test\Microsoft.VisualStudio.LanguageServices.UnitTests.vbproj (Microsoft.VisualStudio.LanguageServices.UnitTests)
' Licensed to the .NET Foundation under one or more agreements.
' The .NET Foundation licenses this file to you under the MIT license.
' See the LICENSE file in the project root for more information.
 
Imports System.Collections.Immutable
Imports System.Threading
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.Diagnostics
Imports Microsoft.CodeAnalysis.Editor
Imports Microsoft.CodeAnalysis.Editor.UnitTests
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces
Imports Microsoft.CodeAnalysis.Shared.TestHooks
Imports Microsoft.CodeAnalysis.SolutionCrawler
Imports Microsoft.CodeAnalysis.Test.Utilities
Imports Microsoft.CodeAnalysis.Text.Shared.Extensions
Imports Microsoft.CodeAnalysis.UnitTests
Imports Microsoft.VisualStudio.Text.Tagging
Imports Roslyn.Test.Utilities
Imports Roslyn.Utilities
 
Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Diagnostics
    <UseExportProvider, Trait(Traits.Feature, Traits.Features.Tagging)>
    Public Class DefaultDiagnosticUpdateSourceTests
        Private Shared ReadOnly s_compositionWithMockDiagnosticUpdateSourceRegistrationService As TestComposition = EditorTestCompositions.EditorFeatures _
            .AddExcludedPartTypes(GetType(IDiagnosticUpdateSourceRegistrationService)) _
            .AddParts(GetType(MockDiagnosticUpdateSourceRegistrationService))
 
        Private Shared Function GetDefaultDiagnosticAnalyzerService(workspace As TestWorkspace) As DefaultDiagnosticAnalyzerService
            Dim lazyIncrementalAnalyzerProviders = workspace.ExportProvider.GetExports(Of IIncrementalAnalyzerProvider, IncrementalAnalyzerProviderMetadata)()
            Dim lazyMiscService = lazyIncrementalAnalyzerProviders.Single(Function(lazyProvider) lazyProvider.Metadata.Name = WellKnownSolutionCrawlerAnalyzers.Diagnostic AndAlso lazyProvider.Metadata.HighPriorityForActiveFile = False)
            Return Assert.IsType(Of DefaultDiagnosticAnalyzerService)(lazyMiscService.Value)
        End Function
 
        <WpfFact>
        Public Async Function TestMiscSquiggles() As Task
            Dim code = <code>
class 123 { }
                       </code>
            Using workspace = TestWorkspace.CreateCSharp(code.Value, openDocuments:=True)
 
                Dim analyzerReference = New TestAnalyzerReferenceByLanguage(DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap())
                workspace.TryApplyChanges(workspace.CurrentSolution.WithAnalyzerReferences({analyzerReference}))
 
                Dim diagnosticService = DirectCast(workspace.ExportProvider.GetExportedValue(Of IDiagnosticService), DiagnosticService)
 
                Dim miscService = DirectCast(workspace.GetService(Of IDiagnosticAnalyzerService), DiagnosticAnalyzerService)
 
                DiagnosticProvider.Enable(workspace)
 
                Dim buffer = workspace.Documents.First().GetTextBuffer()
 
                Dim listenerProvider = workspace.ExportProvider.GetExportedValue(Of IAsynchronousOperationListenerProvider)
 
                Dim provider = workspace.ExportProvider.GetExportedValues(Of ITaggerProvider)().OfType(Of DiagnosticsSquiggleTaggerProvider)().Single()
                Dim tagger = provider.CreateTagger(Of IErrorTag)(buffer)
 
                Using disposable = TryCast(tagger, IDisposable)
                    Dim analyzer = miscService.CreateIncrementalAnalyzer(workspace)
                    Await analyzer.AnalyzeSyntaxAsync(workspace.CurrentSolution.Projects.First().Documents.First(), InvocationReasons.Empty, CancellationToken.None)
 
                    Await listenerProvider.GetWaiter(FeatureAttribute.DiagnosticService).ExpeditedWaitAsync()
                    Await listenerProvider.GetWaiter(FeatureAttribute.ErrorSquiggles).ExpeditedWaitAsync()
 
                    Dim snapshot = buffer.CurrentSnapshot
                    Dim spans = tagger.GetTags(snapshot.GetSnapshotSpanCollection()).ToImmutableArray()
 
                    Assert.NotEmpty(spans)
                    Assert.True(spans.All(Function(s) s.Span.Length > 0))
                End Using
            End Using
        End Function
 
        <Fact>
        Public Async Function TestDefaultDiagnosticProviderSyntaxAndSemantics() As Task
            Dim code = <code>
class A
{
   void Method()
   {
        M m = null
   }
}
                       </code>
 
            Using workspace = TestWorkspace.CreateCSharp(code.Value, openDocuments:=True)
                Dim diagnosticService = DirectCast(workspace.ExportProvider.GetExportedValue(Of IDiagnosticService), DiagnosticService)
 
                Dim analyzerReference = New TestAnalyzerReferenceByLanguage(DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap())
                workspace.TryApplyChanges(workspace.CurrentSolution.WithAnalyzerReferences({analyzerReference}))
 
                Dim miscService = GetDefaultDiagnosticAnalyzerService(workspace)
                Assert.False(miscService.SupportGetDiagnostics)
 
                DiagnosticProvider.Enable(workspace)
 
                Dim document = workspace.CurrentSolution.Projects.First().Documents.First()
                Dim analyzer = miscService.CreateIncrementalAnalyzer(workspace)
 
                Await analyzer.AnalyzeSyntaxAsync(document, InvocationReasons.Empty, CancellationToken.None)
                Await analyzer.AnalyzeDocumentAsync(document, Nothing, InvocationReasons.Empty, CancellationToken.None)
 
                Dim listenerProvider = workspace.ExportProvider.GetExportedValue(Of IAsynchronousOperationListenerProvider)
                Await listenerProvider.GetWaiter(FeatureAttribute.DiagnosticService).ExpeditedWaitAsync()
 
                Dim diagnostics = Await diagnosticService.GetDiagnosticsAsync(
                    workspace, document.Project.Id, document.Id, Nothing, includeSuppressedDiagnostics:=False, CancellationToken.None)
 
                Assert.Equal(2, diagnostics.Length)
            End Using
        End Function
 
        <Fact(Skip:="https://github.com/dotnet/roslyn/issues/45877")>
        Public Async Function TestDefaultDiagnosticProviderSemantic() As Task
            Dim code = <code>
class A
{
   void Method()
   {
        M m = null
   }
}
                       </code>
 
            Using workspace = TestWorkspace.CreateCSharp(code.Value, openDocuments:=True)
                Dim diagnosticService = DirectCast(workspace.ExportProvider.GetExportedValue(Of IDiagnosticService), DiagnosticService)
 
                Dim analyzerReference = New TestAnalyzerReferenceByLanguage(DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap())
                workspace.TryApplyChanges(workspace.CurrentSolution.WithAnalyzerReferences({analyzerReference}))
 
                Dim miscService = GetDefaultDiagnosticAnalyzerService(workspace)
                Assert.False(miscService.SupportGetDiagnostics)
 
                DiagnosticProvider.Enable(workspace)
 
                Dim document = workspace.CurrentSolution.Projects.First().Documents.First()
                Dim analyzer = miscService.CreateIncrementalAnalyzer(workspace)
                Await analyzer.AnalyzeSyntaxAsync(document, InvocationReasons.Empty, CancellationToken.None)
                Await analyzer.AnalyzeDocumentAsync(document, Nothing, InvocationReasons.Empty, CancellationToken.None)
 
                Dim listenerProvider = workspace.ExportProvider.GetExportedValue(Of IAsynchronousOperationListenerProvider)
                Await listenerProvider.GetWaiter(FeatureAttribute.DiagnosticService).ExpeditedWaitAsync()
 
                Dim diagnostics = Await diagnosticService.GetDiagnosticsAsync(
                    workspace, document.Project.Id, document.Id, Nothing, includeSuppressedDiagnostics:=False, CancellationToken.None)
 
                ' error CS0246: The type or namespace name 'M' could not be found
                AssertEx.Equal({"CS0246"}, diagnostics.Select(Function(d) d.Id))
            End Using
        End Function
 
        <Fact>
        Public Async Function TestDefaultDiagnosticProviderAll() As Task
            Dim code = <code>
class A
{
   void Method()
   {
        M m = null
   }
}
                       </code>
 
            Using workspace = TestWorkspace.CreateCSharp(code.Value, openDocuments:=True)
                Dim diagnosticService = DirectCast(workspace.ExportProvider.GetExportedValue(Of IDiagnosticService), DiagnosticService)
 
                Dim analyzerReference = New TestAnalyzerReferenceByLanguage(DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap())
                workspace.TryApplyChanges(workspace.CurrentSolution.WithAnalyzerReferences({analyzerReference}))
 
                Dim miscService = GetDefaultDiagnosticAnalyzerService(workspace)
                Assert.False(miscService.SupportGetDiagnostics)
 
                DiagnosticProvider.Enable(workspace)
 
                Dim document = workspace.CurrentSolution.Projects.First().Documents.First()
                Dim analyzer = miscService.CreateIncrementalAnalyzer(workspace)
                Await analyzer.AnalyzeSyntaxAsync(document, InvocationReasons.Empty, CancellationToken.None)
                Await analyzer.AnalyzeDocumentAsync(document, Nothing, InvocationReasons.Empty, CancellationToken.None)
 
                Dim listenerProvider = workspace.ExportProvider.GetExportedValue(Of IAsynchronousOperationListenerProvider)
                Await listenerProvider.GetWaiter(FeatureAttribute.DiagnosticService).ExpeditedWaitAsync()
 
                Dim diagnostics = Await diagnosticService.GetDiagnosticsAsync(
                    workspace, document.Project.Id, document.Id, Nothing, includeSuppressedDiagnostics:=False, CancellationToken.None)
 
                ' error CS1002: ; expected
                ' error CS0246: The type or namespace name 'M' could not be found
                AssertEx.SetEqual({"CS1002", "CS0246"}, diagnostics.Select(Function(d) d.Id))
            End Using
        End Function
 
        <Fact(Skip:="https://github.com/dotnet/roslyn/issues/45877")>
        Public Async Function TestDefaultDiagnosticProviderRemove() As Task
            Dim code = <code>
class A
{
   void Method()
   {
        M m = null
   }
}
                       </code>
 
            Using workspace = TestWorkspace.CreateCSharp(code.Value, openDocuments:=True)
                Dim diagnosticService = DirectCast(workspace.ExportProvider.GetExportedValue(Of IDiagnosticService), DiagnosticService)
 
                Dim analyzerReference = New TestAnalyzerReferenceByLanguage(DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap())
                workspace.TryApplyChanges(workspace.CurrentSolution.WithAnalyzerReferences({analyzerReference}))
 
                Dim miscService = GetDefaultDiagnosticAnalyzerService(workspace)
                Assert.False(miscService.SupportGetDiagnostics)
 
                DiagnosticProvider.Enable(workspace)
 
                Dim document = workspace.CurrentSolution.Projects.First().Documents.First()
                Dim analyzer = miscService.CreateIncrementalAnalyzer(workspace)
 
                Await analyzer.AnalyzeSyntaxAsync(document, InvocationReasons.Empty, CancellationToken.None)
                Await analyzer.AnalyzeDocumentAsync(document, Nothing, InvocationReasons.Empty, CancellationToken.None)
                Await analyzer.RemoveDocumentAsync(document.Id, CancellationToken.None)
 
                Dim listenerProvider = workspace.ExportProvider.GetExportedValue(Of IAsynchronousOperationListenerProvider)
                Await listenerProvider.GetWaiter(FeatureAttribute.DiagnosticService).ExpeditedWaitAsync()
 
                Dim diagnostics = Await diagnosticService.GetDiagnosticsAsync(
                    workspace, document.Project.Id, document.Id, Nothing, includeSuppressedDiagnostics:=False, CancellationToken.None)
 
                AssertEx.Empty(diagnostics)
            End Using
        End Function
 
        <Fact>
        Public Async Function TestMiscCSharpErrorSource() As Tasks.Task
            Dim code = <code>
class 123 { }
                       </code>
            Using workspace = TestWorkspace.CreateCSharp(code.Value, composition:=s_compositionWithMockDiagnosticUpdateSourceRegistrationService, openDocuments:=True)
                Dim analyzerReference = New TestAnalyzerReferenceByLanguage(DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap())
                workspace.TryApplyChanges(workspace.CurrentSolution.WithAnalyzerReferences({analyzerReference}))
 
                Dim registrationService = Assert.IsType(Of MockDiagnosticUpdateSourceRegistrationService)(workspace.GetService(Of IDiagnosticUpdateSourceRegistrationService)())
                Dim miscService = GetDefaultDiagnosticAnalyzerService(workspace)
 
                DiagnosticProvider.Enable(workspace)
 
                Dim buildTool = String.Empty
 
                AddHandler miscService.DiagnosticsUpdated, Sub(e, a)
                                                               Dim id = DirectCast(a.Id, BuildToolId)
                                                               buildTool = id.BuildTool
                                                           End Sub
 
                Dim analyzer = miscService.CreateIncrementalAnalyzer(workspace)
                Await analyzer.AnalyzeSyntaxAsync(workspace.CurrentSolution.Projects.First().Documents.First(), InvocationReasons.Empty, CancellationToken.None)
 
                Assert.Equal(PredefinedBuildTools.Live, buildTool)
            End Using
        End Function
 
        <Fact>
        Public Async Function TestMiscVBErrorSource() As Task
            Dim code = <code>
Class 123
End Class
                       </code>
            Using workspace = TestWorkspace.CreateVisualBasic(code.Value, composition:=s_compositionWithMockDiagnosticUpdateSourceRegistrationService, openDocuments:=True)
                Dim analyzerReference = New TestAnalyzerReferenceByLanguage(DiagnosticExtensions.GetCompilerDiagnosticAnalyzersMap())
                workspace.TryApplyChanges(workspace.CurrentSolution.WithAnalyzerReferences({analyzerReference}))
 
                Dim registrationService = Assert.IsType(Of MockDiagnosticUpdateSourceRegistrationService)(workspace.GetService(Of IDiagnosticUpdateSourceRegistrationService)())
                Dim miscService = GetDefaultDiagnosticAnalyzerService(workspace)
 
                DiagnosticProvider.Enable(workspace)
 
                Dim buildTool = String.Empty
 
                AddHandler miscService.DiagnosticsUpdated, Sub(e, a)
                                                               Dim id = DirectCast(a.Id, BuildToolId)
                                                               buildTool = id.BuildTool
                                                           End Sub
 
                Dim analyzer = miscService.CreateIncrementalAnalyzer(workspace)
                Await analyzer.AnalyzeSyntaxAsync(workspace.CurrentSolution.Projects.First().Documents.First(), InvocationReasons.Empty, CancellationToken.None)
 
                Assert.Equal(PredefinedBuildTools.Live, buildTool)
            End Using
        End Function
 
        <Fact>
        Public Async Function TestMiscDocumentWithNoCompilationWithScriptSemantic() As Task
            Dim test =
                <Workspace>
                    <Project Language="NoCompilation">
                        <Document FilePath="Somthing.something">
                            <ParseOptions Kind="Script"/>
                            Dummy content.
                        </Document>
                    </Project>
                </Workspace>
 
            Dim analyzerMap = ImmutableDictionary(Of String, ImmutableArray(Of DiagnosticAnalyzer)).Empty.Add(
                NoCompilationConstants.LanguageName, ImmutableArray.Create(Of DiagnosticAnalyzer)(New DiagnosticAnalyzerWithSemanticError()))
 
            Dim composition = EditorTestCompositions.EditorFeatures.AddParts(
                GetType(NoCompilationContentTypeLanguageService),
                GetType(NoCompilationContentTypeDefinitions))
 
            Using workspace = TestWorkspace.CreateWorkspace(test, openDocuments:=True, composition:=composition)
                Dim analyzerReference = New TestAnalyzerReferenceByLanguage(analyzerMap)
                workspace.TryApplyChanges(workspace.CurrentSolution.WithAnalyzerReferences({analyzerReference}))
 
                Dim diagnosticService = DirectCast(workspace.ExportProvider.GetExportedValue(Of IDiagnosticService), DiagnosticService)
 
                Dim miscService = GetDefaultDiagnosticAnalyzerService(workspace)
                Assert.False(miscService.SupportGetDiagnostics)
 
                DiagnosticProvider.Enable(workspace)
 
                Dim document = workspace.CurrentSolution.Projects.First().Documents.First()
                Dim analyzer = miscService.CreateIncrementalAnalyzer(workspace)
 
                Await analyzer.AnalyzeSyntaxAsync(document, InvocationReasons.Empty, CancellationToken.None)
                Await analyzer.AnalyzeDocumentAsync(document, Nothing, InvocationReasons.Empty, CancellationToken.None)
 
                Dim listenerProvider = workspace.ExportProvider.GetExportedValue(Of IAsynchronousOperationListenerProvider)
                Await listenerProvider.GetWaiter(FeatureAttribute.DiagnosticService).ExpeditedWaitAsync()
 
                Dim diagnostics = Await diagnosticService.GetDiagnosticsAsync(
                    workspace, document.Project.Id, document.Id, Nothing, includeSuppressedDiagnostics:=False, CancellationToken.None)
 
                Assert.Single(diagnostics)
            End Using
        End Function
 
        <DiagnosticAnalyzer(NoCompilationConstants.LanguageName)>
        Private Class DiagnosticAnalyzerWithSemanticError
            Inherits DocumentDiagnosticAnalyzer
 
            Public Shared ReadOnly Descriptor As DiagnosticDescriptor = New DiagnosticDescriptor(
                "Id", "Error", "Error", "Error", DiagnosticSeverity.Error, isEnabledByDefault:=True)
 
            Public Overrides ReadOnly Property SupportedDiagnostics As ImmutableArray(Of DiagnosticDescriptor)
                Get
                    Return ImmutableArray.Create(Descriptor)
                End Get
            End Property
 
            Public Overrides Function AnalyzeSemanticsAsync(document As Document, cancellationToken As CancellationToken) As Task(Of ImmutableArray(Of Diagnostic))
                Return Task.FromResult(ImmutableArray.Create(Diagnostic.Create(Descriptor, Location.Create(document.FilePath, Nothing, Nothing))))
            End Function
 
            Public Overrides Function AnalyzeSyntaxAsync(document As Document, cancellationToken As CancellationToken) As Task(Of ImmutableArray(Of Diagnostic))
                Return SpecializedTasks.EmptyImmutableArray(Of Diagnostic)()
            End Function
        End Class
    End Class
End Namespace