File: Diagnostics\DiagnosticAnalyzerTests.vb
Web Access
Project: src\src\Compilers\VisualBasic\Test\Semantic\Microsoft.CodeAnalysis.VisualBasic.Semantic.UnitTests.vbproj (Microsoft.CodeAnalysis.VisualBasic.Semantic.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.Concurrent
Imports System.Collections.Immutable
Imports System.Runtime.Serialization
Imports System.Threading
Imports Microsoft.CodeAnalysis.CommonDiagnosticAnalyzers
Imports Microsoft.CodeAnalysis.Diagnostics
Imports Microsoft.CodeAnalysis.Diagnostics.VisualBasic
Imports Microsoft.CodeAnalysis.FlowAnalysis
Imports Microsoft.CodeAnalysis.PooledObjects
Imports Microsoft.CodeAnalysis.Test.Utilities
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports Roslyn.Test.Utilities
 
Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests.Semantics
 
    Partial Public Class DiagnosticAnalyzerTests
        Inherits BasicTestBase
 
        Public Class ComplainAboutX
            Inherits DiagnosticAnalyzer
 
            Private Shared ReadOnly s_CA9999_UseOfVariableThatStartsWithX As DiagnosticDescriptor = New DiagnosticDescriptor(id:="CA9999_UseOfVariableThatStartsWithX", title:="CA9999_UseOfVariableThatStartsWithX", messageFormat:="Use of variable whose name starts with 'x': '{0}'", category:="Test", defaultSeverity:=DiagnosticSeverity.Warning, isEnabledByDefault:=True)
 
            Public Overrides ReadOnly Property SupportedDiagnostics() As ImmutableArray(Of DiagnosticDescriptor)
                Get
                    Return ImmutableArray.Create(s_CA9999_UseOfVariableThatStartsWithX)
                End Get
            End Property
 
            Public Overrides Sub Initialize(context As AnalysisContext)
                context.RegisterSyntaxNodeAction(AddressOf AnalyzeNode, SyntaxKind.IdentifierName)
            End Sub
 
            Public Sub AnalyzeNode(context As SyntaxNodeAnalysisContext)
                Dim id = CType(context.Node, IdentifierNameSyntax)
                If id.Identifier.ValueText.StartsWith("x", StringComparison.Ordinal) Then
                    context.ReportDiagnostic(CodeAnalysis.Diagnostic.Create(s_CA9999_UseOfVariableThatStartsWithX, id.GetLocation, id.Identifier.ValueText))
                End If
            End Sub
        End Class
 
        <Fact>
        Public Sub TestGetEffectiveDiagnostics()
            Dim noneDiagDescriptor = New DiagnosticDescriptor("XX0001", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.Hidden, isEnabledByDefault:=True)
            Dim infoDiagDescriptor = New DiagnosticDescriptor("XX0002", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.Info, isEnabledByDefault:=True)
            Dim warningDiagDescriptor = New DiagnosticDescriptor("XX0003", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.Warning, isEnabledByDefault:=True)
            Dim errorDiagDescriptor = New DiagnosticDescriptor("XX0004", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.Error, isEnabledByDefault:=True)
 
            Dim noneDiag = Microsoft.CodeAnalysis.Diagnostic.Create(noneDiagDescriptor, Location.None)
            Dim infoDiag = Microsoft.CodeAnalysis.Diagnostic.Create(infoDiagDescriptor, Location.None)
            Dim warningDiag = Microsoft.CodeAnalysis.Diagnostic.Create(warningDiagDescriptor, Location.None)
            Dim errorDiag = Microsoft.CodeAnalysis.Diagnostic.Create(errorDiagDescriptor, Location.None)
 
            Dim diags = New Diagnostic() {noneDiag, infoDiag, warningDiag, errorDiag}
 
            ' Escalate all diagnostics to error.
            Dim specificDiagOptions = New Dictionary(Of String, ReportDiagnostic)()
            specificDiagOptions.Add(noneDiagDescriptor.Id, ReportDiagnostic.[Error])
            specificDiagOptions.Add(infoDiagDescriptor.Id, ReportDiagnostic.[Error])
            specificDiagOptions.Add(warningDiagDescriptor.Id, ReportDiagnostic.[Error])
            Dim options = TestOptions.ReleaseDll.WithSpecificDiagnosticOptions(specificDiagOptions)
 
            Dim comp = CreateCompilationWithMscorlib40({""}, options:=options)
            Dim effectiveDiags = comp.GetEffectiveDiagnostics(diags).ToArray()
            Assert.Equal(diags.Length, effectiveDiags.Length)
            For Each effectiveDiag In effectiveDiags
                Assert.True(effectiveDiag.Severity = DiagnosticSeverity.Error)
            Next
 
            ' Suppress all diagnostics.
            ' NOTE: Diagnostics with default severity error cannot be suppressed and its severity cannot be lowered.
            specificDiagOptions = New Dictionary(Of String, ReportDiagnostic)()
            specificDiagOptions.Add(noneDiagDescriptor.Id, ReportDiagnostic.Suppress)
            specificDiagOptions.Add(infoDiagDescriptor.Id, ReportDiagnostic.Suppress)
            specificDiagOptions.Add(warningDiagDescriptor.Id, ReportDiagnostic.Suppress)
            specificDiagOptions.Add(errorDiagDescriptor.Id, ReportDiagnostic.Suppress)
            options = TestOptions.ReleaseDll.WithSpecificDiagnosticOptions(specificDiagOptions)
 
            comp = CreateCompilationWithMscorlib40({""}, options:=options)
            effectiveDiags = comp.GetEffectiveDiagnostics(diags).ToArray()
            Assert.Equal(0, effectiveDiags.Length)
 
            ' Shuffle diagnostic severity.
            specificDiagOptions = New Dictionary(Of String, ReportDiagnostic)()
            specificDiagOptions.Add(noneDiagDescriptor.Id, ReportDiagnostic.Info)
            specificDiagOptions.Add(infoDiagDescriptor.Id, ReportDiagnostic.Hidden)
            specificDiagOptions.Add(warningDiagDescriptor.Id, ReportDiagnostic.[Error])
            specificDiagOptions.Add(errorDiagDescriptor.Id, ReportDiagnostic.Warn)
            options = TestOptions.ReleaseDll.WithSpecificDiagnosticOptions(specificDiagOptions)
 
            comp = CreateCompilationWithMscorlib40({""}, options:=options)
            effectiveDiags = comp.GetEffectiveDiagnostics(diags).ToArray()
            Assert.Equal(diags.Length, effectiveDiags.Length)
            Dim diagIds = New HashSet(Of String)(diags.[Select](Function(d) d.Id))
            For Each effectiveDiag In effectiveDiags
                Assert.[True](diagIds.Remove(effectiveDiag.Id))
 
                Select Case effectiveDiag.Severity
                    Case DiagnosticSeverity.Hidden
                        Assert.Equal(infoDiagDescriptor.Id, effectiveDiag.Id)
 
                    Case DiagnosticSeverity.Info
                        Assert.Equal(noneDiagDescriptor.Id, effectiveDiag.Id)
                        Exit Select
 
                    Case DiagnosticSeverity.Warning
                        Assert.Equal(errorDiagDescriptor.Id, effectiveDiag.Id)
                        Exit Select
 
                    Case DiagnosticSeverity.Error
                        Assert.Equal(warningDiagDescriptor.Id, effectiveDiag.Id)
                        Exit Select
                    Case Else
 
                        Throw ExceptionUtilities.Unreachable
                End Select
            Next
 
            Assert.Empty(diagIds)
 
        End Sub
 
        <Fact>
        Public Sub TestGetEffectiveDiagnosticsGlobal()
            Dim noneDiagDescriptor = New DiagnosticDescriptor("XX0001", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.Hidden, isEnabledByDefault:=True)
            Dim infoDiagDescriptor = New DiagnosticDescriptor("XX0002", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.Info, isEnabledByDefault:=True)
            Dim warningDiagDescriptor = New DiagnosticDescriptor("XX0003", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.Warning, isEnabledByDefault:=True)
            Dim errorDiagDescriptor = New DiagnosticDescriptor("XX0004", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.[Error], isEnabledByDefault:=True)
 
            Dim noneDiag = Microsoft.CodeAnalysis.Diagnostic.Create(noneDiagDescriptor, Location.None)
            Dim infoDiag = Microsoft.CodeAnalysis.Diagnostic.Create(infoDiagDescriptor, Location.None)
            Dim warningDiag = Microsoft.CodeAnalysis.Diagnostic.Create(warningDiagDescriptor, Location.None)
            Dim errorDiag = Microsoft.CodeAnalysis.Diagnostic.Create(errorDiagDescriptor, Location.None)
 
            Dim diags = New Diagnostic() {noneDiag, infoDiag, warningDiag, errorDiag}
 
            Dim options = TestOptions.ReleaseDll.WithGeneralDiagnosticOption(ReportDiagnostic.Default)
            Dim comp = CreateCompilationWithMscorlib40({""}, options:=options)
            Dim effectiveDiags = comp.GetEffectiveDiagnostics(diags).ToArray()
            Assert.Equal(4, effectiveDiags.Length)
 
            options = TestOptions.ReleaseDll.WithGeneralDiagnosticOption(ReportDiagnostic.Error)
            comp = CreateCompilationWithMscorlib40({""}, options:=options)
            effectiveDiags = comp.GetEffectiveDiagnostics(diags).ToArray()
            Assert.Equal(4, effectiveDiags.Length)
            Assert.Equal(1, effectiveDiags.Count(Function(d) d.IsWarningAsError))
 
            options = TestOptions.ReleaseDll.WithGeneralDiagnosticOption(ReportDiagnostic.Warn)
            comp = CreateCompilationWithMscorlib40({""}, options:=options)
            effectiveDiags = comp.GetEffectiveDiagnostics(diags).ToArray()
            Assert.Equal(4, effectiveDiags.Length)
            Assert.Equal(1, effectiveDiags.Count(Function(d) d.Severity = DiagnosticSeverity.Error))
            Assert.Equal(1, effectiveDiags.Count(Function(d) d.Severity = DiagnosticSeverity.Warning))
 
            options = TestOptions.ReleaseDll.WithGeneralDiagnosticOption(ReportDiagnostic.Info)
            comp = CreateCompilationWithMscorlib40({""}, options:=options)
            effectiveDiags = comp.GetEffectiveDiagnostics(diags).ToArray()
            Assert.Equal(4, effectiveDiags.Length)
            Assert.Equal(1, effectiveDiags.Count(Function(d) d.Severity = DiagnosticSeverity.Error))
            Assert.Equal(1, effectiveDiags.Count(Function(d) d.Severity = DiagnosticSeverity.Info))
 
            options = TestOptions.ReleaseDll.WithGeneralDiagnosticOption(ReportDiagnostic.Hidden)
            comp = CreateCompilationWithMscorlib40({""}, options:=options)
            effectiveDiags = comp.GetEffectiveDiagnostics(diags).ToArray()
            Assert.Equal(4, effectiveDiags.Length)
            Assert.Equal(1, effectiveDiags.Count(Function(d) d.Severity = DiagnosticSeverity.Error))
            Assert.Equal(1, effectiveDiags.Count(Function(d) d.Severity = DiagnosticSeverity.Hidden))
 
            options = TestOptions.ReleaseDll.WithGeneralDiagnosticOption(ReportDiagnostic.Suppress)
            comp = CreateCompilationWithMscorlib40({""}, options:=options)
            effectiveDiags = comp.GetEffectiveDiagnostics(diags).ToArray()
            Assert.Equal(2, effectiveDiags.Length)
            Assert.Equal(1, effectiveDiags.Count(Function(d) d.Severity = DiagnosticSeverity.Error))
            Assert.Equal(1, effectiveDiags.Count(Function(d) d.Severity = DiagnosticSeverity.Hidden))
 
        End Sub
 
        <Fact>
        Public Sub TestDisabledDiagnostics()
            Dim disabledDiagDescriptor = New DiagnosticDescriptor("XX001", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.Warning, isEnabledByDefault:=False)
            Dim enabledDiagDescriptor = New DiagnosticDescriptor("XX002", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.Warning, isEnabledByDefault:=True)
 
            Dim disabledDiag = CodeAnalysis.Diagnostic.Create(disabledDiagDescriptor, Location.None)
            Dim enabledDiag = CodeAnalysis.Diagnostic.Create(enabledDiagDescriptor, Location.None)
 
            Dim diags = {disabledDiag, enabledDiag}
 
            ' Verify that only the enabled diag shows up after filtering.
            Dim options = TestOptions.ReleaseDll
            Dim comp = CreateCompilationWithMscorlib40({""}, options:=options)
            Dim effectiveDiags = comp.GetEffectiveDiagnostics(diags).ToArray()
            Assert.Equal(1, effectiveDiags.Length)
            Assert.Contains(enabledDiag, effectiveDiags)
 
            ' If the disabled diag was enabled through options, then it should show up.
            Dim specificDiagOptions = New Dictionary(Of String, ReportDiagnostic)()
            specificDiagOptions.Add(disabledDiagDescriptor.Id, ReportDiagnostic.Warn)
            specificDiagOptions.Add(enabledDiagDescriptor.Id, ReportDiagnostic.Suppress)
 
            options = TestOptions.ReleaseDll.WithSpecificDiagnosticOptions(specificDiagOptions)
            comp = CreateCompilationWithMscorlib40({""}, options:=options)
            effectiveDiags = comp.GetEffectiveDiagnostics(diags).ToArray()
            Assert.Equal(1, effectiveDiags.Length)
            Assert.Contains(disabledDiag, effectiveDiags)
        End Sub
 
        Public Class FullyDisabledAnalyzer
            Inherits DiagnosticAnalyzer
 
            Public Shared desc1 As New DiagnosticDescriptor("XX001", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.Warning, isEnabledByDefault:=False)
            Public Shared desc2 As New DiagnosticDescriptor("XX002", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.Warning, isEnabledByDefault:=False)
 
            Public Overrides ReadOnly Property SupportedDiagnostics As ImmutableArray(Of DiagnosticDescriptor)
                Get
                    Return ImmutableArray.Create(desc1, desc2)
                End Get
            End Property
 
            Public Overrides Sub Initialize(context As AnalysisContext)
            End Sub
        End Class
 
        Public Class PartiallyDisabledAnalyzer
            Inherits DiagnosticAnalyzer
 
            Public Shared desc1 As New DiagnosticDescriptor("XX003", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.Warning, isEnabledByDefault:=False)
            Public Shared desc2 As New DiagnosticDescriptor("XX004", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.Warning, isEnabledByDefault:=True)
 
            Public Overrides ReadOnly Property SupportedDiagnostics As ImmutableArray(Of DiagnosticDescriptor)
                Get
                    Return ImmutableArray.Create(desc1, desc2)
                End Get
            End Property
 
            Public Overrides Sub Initialize(context As AnalysisContext)
            End Sub
        End Class
 
        <Fact, Obsolete("IsDiagnosticAnalyzerSuppressed is an obsolete public API")>
        Public Sub TestDisabledAnalyzers()
            Dim fullyDisabledAnalyzer = New FullyDisabledAnalyzer()
            Dim partiallyDisabledAnalyzer = New PartiallyDisabledAnalyzer()
 
            Dim options = TestOptions.ReleaseDll
            Assert.True(fullyDisabledAnalyzer.IsDiagnosticAnalyzerSuppressed(options))
            Assert.False(partiallyDisabledAnalyzer.IsDiagnosticAnalyzerSuppressed(options))
 
            Dim specificDiagOptions = New Dictionary(Of String, ReportDiagnostic)()
            specificDiagOptions.Add(FullyDisabledAnalyzer.desc1.Id, ReportDiagnostic.Warn)
            specificDiagOptions.Add(PartiallyDisabledAnalyzer.desc2.Id, ReportDiagnostic.Suppress)
 
            options = TestOptions.ReleaseDll.WithSpecificDiagnosticOptions(specificDiagOptions)
            Assert.False(fullyDisabledAnalyzer.IsDiagnosticAnalyzerSuppressed(options))
            Assert.True(partiallyDisabledAnalyzer.IsDiagnosticAnalyzerSuppressed(options))
        End Sub
 
        Public Class ModuleStatementAnalyzer
            Inherits DiagnosticAnalyzer
 
            Public Shared desc1 As New DiagnosticDescriptor("XX001", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.Warning, isEnabledByDefault:=True)
 
            Public Overrides ReadOnly Property SupportedDiagnostics As ImmutableArray(Of DiagnosticDescriptor)
                Get
                    Return ImmutableArray.Create(desc1)
                End Get
            End Property
 
            Public Overrides Sub Initialize(context As AnalysisContext)
                context.RegisterSyntaxNodeAction(AddressOf AnalyzeNode, SyntaxKind.ModuleStatement)
            End Sub
 
            Public Sub AnalyzeNode(context As SyntaxNodeAnalysisContext)
                Dim moduleStatement = DirectCast(context.Node, ModuleStatementSyntax)
                context.ReportDiagnostic(CodeAnalysis.Diagnostic.Create(desc1, context.Node.GetLocation))
            End Sub
        End Class
 
        <Fact>
        Public Sub TestModuleStatementSyntaxAnalyzer()
            Dim analyzer = New ModuleStatementAnalyzer()
            Dim source = <compilation>
                             <file name="c.vb">
                                 <![CDATA[
Public Module ThisModule
End Module
]]>
                             </file>
                         </compilation>
 
            Dim comp = CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntime(source)
            comp.VerifyDiagnostics()
            comp.VerifyAnalyzerDiagnostics({analyzer}, Nothing, Nothing, Diagnostic("XX001", <![CDATA[Public Module ThisModule]]>))
        End Sub
 
        Public Class MockSymbolAnalyzer
            Inherits DiagnosticAnalyzer
 
            Public Shared desc1 As New DiagnosticDescriptor("XX001", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.Warning, isEnabledByDefault:=True)
 
            Public Overrides ReadOnly Property SupportedDiagnostics As ImmutableArray(Of DiagnosticDescriptor)
                Get
                    Return ImmutableArray.Create(desc1)
                End Get
            End Property
 
            Public Overrides Sub Initialize(context As AnalysisContext)
                context.RegisterSymbolAction(AddressOf AnalyzeSymbol, SymbolKind.NamedType)
            End Sub
 
            Public Sub AnalyzeSymbol(context As SymbolAnalysisContext)
                Dim sourceLoc = context.Symbol.Locations.First(Function(l) l.IsInSource)
                context.ReportDiagnostic(CodeAnalysis.Diagnostic.Create(desc1, sourceLoc))
            End Sub
        End Class
 
        <WorkItem(998724, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/998724")>
        <Fact>
        Public Sub TestSymbolAnalyzerNotInvokedForMyTemplateSymbols()
            Dim analyzer = New MockSymbolAnalyzer()
            Dim sources = <compilation>
                              <file name="c.vb">
                                  <![CDATA[
Public Class C
End Class
]]>
                              </file>
                          </compilation>
 
            Dim compilation = CreateCompilationWithMscorlib40AndReferences(sources,
                references:={SystemCoreRef, MsvbRef},
                options:=TestOptions.ReleaseDll)
 
            Dim MyTemplate = MyTemplateTests.GetMyTemplateTree(compilation)
            Assert.NotNull(MyTemplate)
 
            compilation.VerifyDiagnostics()
            compilation.VerifyAnalyzerDiagnostics({analyzer}, Nothing, Nothing, Diagnostic("XX001", <![CDATA[C]]>))
        End Sub
 
        Public Class NamespaceAndTypeNodeAnalyzer
            Inherits DiagnosticAnalyzer
 
            Public Shared desc1 As New DiagnosticDescriptor("XX001", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.Warning, isEnabledByDefault:=True)
 
            Public Overrides ReadOnly Property SupportedDiagnostics As ImmutableArray(Of DiagnosticDescriptor)
                Get
                    Return ImmutableArray.Create(desc1)
                End Get
            End Property
 
            Public Overrides Sub Initialize(context As AnalysisContext)
                context.RegisterSyntaxNodeAction(AddressOf AnalyzeNode, SyntaxKind.NamespaceBlock, SyntaxKind.ClassBlock)
            End Sub
 
            Public Sub AnalyzeNode(context As SyntaxNodeAnalysisContext)
                Dim location As Location = Nothing
                Select Case context.Node.Kind
                    Case SyntaxKind.NamespaceBlock
                        location = DirectCast(context.Node, NamespaceBlockSyntax).NamespaceStatement.Name.GetLocation
                    Case SyntaxKind.ClassBlock
                        location = DirectCast(context.Node, ClassBlockSyntax).BlockStatement.Identifier.GetLocation
                End Select
                context.ReportDiagnostic(CodeAnalysis.Diagnostic.Create(desc1, location))
            End Sub
        End Class
 
        <Fact>
        Public Sub TestSyntaxAnalyzerInvokedForNamespaceBlockAndClassBlock()
            Dim analyzer = New NamespaceAndTypeNodeAnalyzer()
            Dim sources = <compilation>
                              <file name="c.vb">
                                  <![CDATA[
Namespace N
    Public Class C
    End Class
End Namespace
]]>
                              </file>
                          </compilation>
 
            Dim compilation = CreateCompilationWithMscorlib40AndReferences(sources,
                references:={SystemCoreRef, MsvbRef},
                options:=TestOptions.ReleaseDll)
 
            compilation.VerifyDiagnostics()
            compilation.VerifyAnalyzerDiagnostics({analyzer}, Nothing, Nothing,
                Diagnostic("XX001", <![CDATA[N]]>),
                Diagnostic("XX001", <![CDATA[C]]>))
        End Sub
 
        Private Class CodeBlockAnalyzer
            Inherits DiagnosticAnalyzer
 
            Private Shared ReadOnly s_descriptor As DiagnosticDescriptor = DescriptorFactory.CreateSimpleDescriptor("CodeBlockDiagnostic")
 
            Public Overrides ReadOnly Property SupportedDiagnostics As ImmutableArray(Of DiagnosticDescriptor)
                Get
                    Return ImmutableArray.Create(s_descriptor)
                End Get
            End Property
 
            Public Overrides Sub Initialize(context As AnalysisContext)
                context.RegisterCodeBlockAction(AddressOf OnCodeBlock)
            End Sub
 
            Private Shared Sub OnCodeBlock(context As CodeBlockAnalysisContext)
                context.ReportDiagnostic(CodeAnalysis.Diagnostic.Create(s_descriptor, context.OwningSymbol.DeclaringSyntaxReferences.First.GetLocation))
            End Sub
        End Class
 
        <Fact, WorkItem(1008059, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1008059")>
        Public Sub TestCodeBlockAnalyzersForNoExecutableCode()
            Dim analyzer = New CodeBlockAnalyzer()
            Dim sources = <compilation>
                              <file name="c.vb">
                                  <![CDATA[
Public MustInherit Class C
    Public Property P() As Integer
    Public field As Integer
    Public MustOverride Sub Method()
End Class
]]>
                              </file>
                          </compilation>
 
            Dim compilation = CreateCompilationWithMscorlib40AndReferences(sources,
                references:={SystemCoreRef, MsvbRef},
                options:=TestOptions.ReleaseDll)
 
            compilation.VerifyDiagnostics()
            compilation.VerifyAnalyzerDiagnostics({analyzer})
        End Sub
 
        <Fact, WorkItem(1008059, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1008059")>
        Public Sub TestCodeBlockAnalyzersForEmptyMethodBody()
            Dim analyzer = New CodeBlockAnalyzer()
            Dim sources = <compilation>
                              <file name="c.vb">
                                  <![CDATA[
Public Class C
    Public Sub Method()
    End Sub
End Class
]]>
                              </file>
                          </compilation>
 
            Dim compilation = CreateCompilationWithMscorlib40AndReferences(sources,
                references:={SystemCoreRef, MsvbRef},
                options:=TestOptions.ReleaseDll)
 
            compilation.VerifyDiagnostics()
            compilation.VerifyAnalyzerDiagnostics({analyzer}, Nothing, Nothing, Diagnostic("CodeBlockDiagnostic", <![CDATA[Public Sub Method()]]>))
        End Sub
 
        <Fact, WorkItem(1096600, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1096600")>
        Private Sub TestDescriptorForConfigurableCompilerDiagnostics()
            ' Verify that all configurable compiler diagnostics, i.e. all non-error diagnostics,
            ' have a non-null and non-empty Title and Category.
            ' These diagnostic descriptor fields show up in the ruleset editor and hence must have a valid value.
 
            Dim analyzer = New VisualBasicCompilerDiagnosticAnalyzer()
            For Each descriptor In analyzer.SupportedDiagnostics
                Assert.Equal(descriptor.IsEnabledByDefault, True)
 
                If descriptor.IsNotConfigurable() Then
                    Continue For
                End If
 
                Dim title = descriptor.Title.ToString()
                If String.IsNullOrEmpty(title) Then
                    Dim id = Integer.Parse(descriptor.Id.Substring(2))
                    Dim missingResource = [Enum].GetName(GetType(ERRID), id) & "_Title"
                    Dim message = String.Format("Add resource string named '{0}' for Title of '{1}' to '{2}'", missingResource, descriptor.Id, NameOf(VBResources))
 
                    ' This assert will fire if you are adding a new compiler diagnostic (non-error severity),
                    ' but did not add a title resource string for the diagnostic.
                    Assert.True(False, message)
                End If
 
                Dim category = descriptor.Category
                If String.IsNullOrEmpty(title) Then
                    Dim message = String.Format("'{0}' must have a non-null non-empty 'Category'", descriptor.Id)
                    Assert.True(False, message)
                End If
            Next
        End Sub
 
        Public Class FieldSymbolAnalyzer
            Inherits DiagnosticAnalyzer
 
            Public Shared desc1 As New DiagnosticDescriptor("FieldSymbolDiagnostic", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.Warning, isEnabledByDefault:=True)
 
            Public Overrides ReadOnly Property SupportedDiagnostics As ImmutableArray(Of DiagnosticDescriptor)
                Get
                    Return ImmutableArray.Create(desc1)
                End Get
            End Property
 
            Public Overrides Sub Initialize(context As AnalysisContext)
                context.RegisterSymbolAction(AddressOf AnalyzeSymbol, SymbolKind.Field)
            End Sub
 
            Public Sub AnalyzeSymbol(context As SymbolAnalysisContext)
                Dim sourceLoc = context.Symbol.Locations.First(Function(l) l.IsInSource)
                context.ReportDiagnostic(CodeAnalysis.Diagnostic.Create(desc1, sourceLoc))
            End Sub
        End Class
 
        <Fact, WorkItem(1109126, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1109126")>
        Public Sub TestFieldSymbolAnalyzer_EnumField()
            Dim analyzer = New FieldSymbolAnalyzer()
            Dim sources = <compilation>
                              <file name="c.vb">
                                  <![CDATA[
Public Enum E
    X = 0
End Enum
]]>
                              </file>
                          </compilation>
 
            Dim compilation = CreateCompilationWithMscorlib40AndReferences(sources,
                    references:={SystemCoreRef, MsvbRef},
                    options:=TestOptions.ReleaseDll)
 
            compilation.VerifyDiagnostics()
            compilation.VerifyAnalyzerDiagnostics({analyzer}, Nothing, Nothing,
                Diagnostic("FieldSymbolDiagnostic", <![CDATA[X]]>))
        End Sub
 
        <Fact, WorkItem(1111667, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1111667")>
        Public Sub TestFieldSymbolAnalyzer_FieldWithoutInitializer()
            Dim analyzer = New FieldSymbolAnalyzer()
            Dim sources = <compilation>
                              <file name="c.vb">
                                  <![CDATA[
Public Class TestClass
    Public Field As System.IntPtr
End Class
]]>
                              </file>
                          </compilation>
 
            Dim compilation = CreateCompilationWithMscorlib40AndReferences(sources,
                    references:={SystemCoreRef, MsvbRef},
                    options:=TestOptions.ReleaseDll)
 
            compilation.VerifyDiagnostics()
            compilation.VerifyAnalyzerDiagnostics({analyzer}, Nothing, Nothing,
                Diagnostic("FieldSymbolDiagnostic", <![CDATA[Field]]>))
        End Sub
 
        Public Class FieldDeclarationAnalyzer
            Inherits DiagnosticAnalyzer
 
            Public Shared desc1 As New DiagnosticDescriptor("FieldDeclarationDiagnostic", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.Warning, isEnabledByDefault:=True)
 
            Public Overrides ReadOnly Property SupportedDiagnostics As ImmutableArray(Of DiagnosticDescriptor)
                Get
                    Return ImmutableArray.Create(desc1)
                End Get
            End Property
 
            Public Overrides Sub Initialize(context As AnalysisContext)
                context.RegisterSyntaxNodeAction(AddressOf AnalyzeNode, SyntaxKind.FieldDeclaration)
            End Sub
 
            Public Sub AnalyzeNode(context As SyntaxNodeAnalysisContext)
                Dim sourceLoc = DirectCast(context.Node, FieldDeclarationSyntax).GetLocation
                context.ReportDiagnostic(CodeAnalysis.Diagnostic.Create(desc1, sourceLoc))
            End Sub
        End Class
 
        <Fact, WorkItem(565, "https://github.com/dotnet/roslyn/issues/565")>
        Public Sub TestFieldDeclarationAnalyzer()
            Dim analyzer = New FieldDeclarationAnalyzer()
            Dim sources = <compilation>
                              <file name="c.vb">
                                  <![CDATA[
Public Class C
    Dim x, y As Integer
    Dim z As Integer
    Dim x2 = 0, y2 = 0
    Dim z2 = 0
End Class
]]>
                              </file>
                          </compilation>
 
            Dim compilation = CreateCompilationWithMscorlib40AndReferences(sources,
                    references:={SystemCoreRef, MsvbRef},
                    options:=TestOptions.ReleaseDll)
 
            compilation.VerifyDiagnostics()
            compilation.VerifyAnalyzerDiagnostics({analyzer}, Nothing, Nothing,
                Diagnostic("FieldDeclarationDiagnostic", <![CDATA[Dim x, y As Integer]]>),
                Diagnostic("FieldDeclarationDiagnostic", <![CDATA[Dim z As Integer]]>),
                Diagnostic("FieldDeclarationDiagnostic", <![CDATA[Dim x2 = 0, y2 = 0]]>),
                Diagnostic("FieldDeclarationDiagnostic", <![CDATA[Dim z2 = 0]]>))
        End Sub
 
        <Fact, WorkItem(4745, "https://github.com/dotnet/roslyn/issues/4745")>
        Public Sub TestNamespaceDeclarationAnalyzer()
            Dim analyzer = New VisualBasicNamespaceDeclarationAnalyzer()
            Dim sources = <compilation>
                              <file name="c.vb">
                                  <![CDATA[
Namespace Goo.Bar.GooBar
End Namespace
]]>
                              </file>
                          </compilation>
 
            Dim compilation = CreateCompilationWithMscorlib40AndReferences(sources,
                    references:={SystemCoreRef, MsvbRef},
                    options:=TestOptions.ReleaseDll)
 
            compilation.VerifyDiagnostics()
            compilation.VerifyAnalyzerDiagnostics({analyzer}, Nothing, Nothing,
                Diagnostic(VisualBasicNamespaceDeclarationAnalyzer.DiagnosticId, <![CDATA[Namespace Goo.Bar.GooBar]]>))
        End Sub
 
        <Fact, WorkItem(5463, "https://github.com/dotnet/roslyn/issues/5463")>
        Public Sub TestObjectCreationInCodeBlockAnalyzer()
            Dim analyzer = New VisualBasicCodeBlockObjectCreationAnalyzer()
            Dim sources = <compilation>
                              <file name="c.vb">
                                  <![CDATA[
Public Class C1
End Class

Public Class C2
End Class

Public Class C3
End Class

Public Class D
    Dim x As C1 = New C1()
    Dim y As New C2()
    Public ReadOnly Property Z As New C3()
End Class
]]>
                              </file>
                          </compilation>
 
            Dim compilation = CreateCompilationWithMscorlib40AndReferences(sources,
                    references:={SystemCoreRef, MsvbRef},
                    options:=TestOptions.ReleaseDll)
 
            compilation.VerifyDiagnostics()
            compilation.VerifyAnalyzerDiagnostics({analyzer}, Nothing, Nothing,
                Diagnostic(VisualBasicCodeBlockObjectCreationAnalyzer.DiagnosticDescriptor.Id, <![CDATA[New C1()]]>),
                Diagnostic(VisualBasicCodeBlockObjectCreationAnalyzer.DiagnosticDescriptor.Id, <![CDATA[New C2()]]>),
                Diagnostic(VisualBasicCodeBlockObjectCreationAnalyzer.DiagnosticDescriptor.Id, <![CDATA[New C3()]]>))
        End Sub
 
        <Fact, WorkItem(1473, "https://github.com/dotnet/roslyn/issues/1473")>
        Public Sub TestReportingNotConfigurableDiagnostic()
            Dim analyzer = New NotConfigurableDiagnosticAnalyzer()
            Dim sources = <compilation>
                              <file name="c.vb">
                                  <![CDATA[]]>
                              </file>
                          </compilation>
 
            ' Verify, not configurable enabled diagnostic is always reported and disabled diagnostic is never reported..
            Dim options = TestOptions.ReleaseDll
            Dim compilation = CreateCompilationWithMscorlib40AndReferences(sources,
                    references:={SystemCoreRef, MsvbRef},
                    options:=options)
 
            compilation.VerifyDiagnostics()
            compilation.VerifyAnalyzerDiagnostics({analyzer}, Nothing, Nothing,
                Diagnostic(NotConfigurableDiagnosticAnalyzer.EnabledRule.Id))
 
            ' Verify not configurable enabled diagnostic cannot be suppressed.
            Dim specificDiagOptions = New Dictionary(Of String, ReportDiagnostic)
            specificDiagOptions.Add(NotConfigurableDiagnosticAnalyzer.EnabledRule.Id, ReportDiagnostic.Suppress)
            options = TestOptions.ReleaseDll.WithSpecificDiagnosticOptions(specificDiagOptions)
 
            compilation = CreateCompilationWithMscorlib40AndReferences(sources,
                    references:={SystemCoreRef, MsvbRef},
                    options:=options)
 
            compilation.VerifyDiagnostics()
            compilation.VerifyAnalyzerDiagnostics({analyzer}, Nothing, Nothing,
                Diagnostic(NotConfigurableDiagnosticAnalyzer.EnabledRule.Id))
 
            ' Verify not configurable disabled diagnostic cannot be enabled.
            specificDiagOptions.Clear()
            specificDiagOptions.Add(NotConfigurableDiagnosticAnalyzer.DisabledRule.Id, ReportDiagnostic.Warn)
            options = TestOptions.ReleaseDll.WithSpecificDiagnosticOptions(specificDiagOptions)
 
            compilation = CreateCompilationWithMscorlib40AndReferences(sources,
                    references:={SystemCoreRef, MsvbRef},
                    options:=options)
 
            compilation.VerifyDiagnostics()
            compilation.VerifyAnalyzerDiagnostics({analyzer}, Nothing, Nothing, Diagnostic(NotConfigurableDiagnosticAnalyzer.EnabledRule.Id))
        End Sub
 
        <Fact, WorkItem(1709, "https://github.com/dotnet/roslyn/issues/1709")>
        Public Sub TestCodeBlockAction()
            Dim analyzer = New CodeBlockActionAnalyzer()
            Dim sources = <compilation>
                              <file name="c.vb">
                                  <![CDATA[
Class C 
    Public Sub M()
    End Sub
End Class
]]>
                              </file>
                          </compilation>
 
            Dim compilation = CreateCompilationWithMscorlib40AndReferences(sources, references:={SystemCoreRef, MsvbRef})
 
            compilation.VerifyDiagnostics()
            compilation.VerifyAnalyzerDiagnostics({analyzer}, Nothing, Nothing,
                Diagnostic(CodeBlockActionAnalyzer.CodeBlockTopLevelRule.Id, <![CDATA[M]]>).WithArguments("M"),
                Diagnostic(CodeBlockActionAnalyzer.CodeBlockPerCompilationRule.Id, <![CDATA[M]]>).WithArguments("M"))
        End Sub
 
        <Fact, WorkItem(1709, "https://github.com/dotnet/roslyn/issues/1709")>
        Public Sub TestCodeBlockAction_OnlyStatelessAction()
            Dim analyzer = New CodeBlockActionAnalyzer(onlyStatelessAction:=True)
            Dim sources = <compilation>
                              <file name="c.vb">
                                  <![CDATA[
Class C 
    Public Sub M()
    End Sub
End Class
]]>
                              </file>
                          </compilation>
 
            Dim compilation = CreateCompilationWithMscorlib40AndReferences(sources, references:={SystemCoreRef, MsvbRef})
 
            compilation.VerifyDiagnostics()
            compilation.VerifyAnalyzerDiagnostics({analyzer}, Nothing, Nothing,
                Diagnostic(CodeBlockActionAnalyzer.CodeBlockTopLevelRule.Id, <![CDATA[M]]>).WithArguments("M"))
        End Sub
 
        Private Shared Sub TestEffectiveSeverity(defaultSeverity As DiagnosticSeverity, expectedEffectiveSeverity As ReportDiagnostic, Optional specificOptions As Dictionary(Of String, ReportDiagnostic) = Nothing, Optional generalOption As ReportDiagnostic = ReportDiagnostic.Default, Optional isEnabledByDefault As Boolean = True)
            specificOptions = If(specificOptions, New Dictionary(Of String, ReportDiagnostic))
            Dim options = New VisualBasicCompilationOptions(OutputKind.ConsoleApplication,
                                                            generalDiagnosticOption:=generalOption,
                                                            specificDiagnosticOptions:=specificOptions)
            Dim descriptor = New DiagnosticDescriptor(id:="Test0001", title:="Test0001", messageFormat:="Test0001", category:="Test0001", defaultSeverity:=defaultSeverity, isEnabledByDefault:=isEnabledByDefault)
            Dim effectiveSeverity = descriptor.GetEffectiveSeverity(options)
            Assert.Equal(expectedEffectiveSeverity, effectiveSeverity)
        End Sub
 
        <Fact>
        <WorkItem(1107500, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1107500")>
        <WorkItem(2598, "https://github.com/dotnet/roslyn/issues/2598")>
        Public Sub EffectiveSeverity_DiagnosticDefault1()
            TestEffectiveSeverity(DiagnosticSeverity.Warning, ReportDiagnostic.Warn)
        End Sub
 
        <Fact>
        <WorkItem(1107500, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1107500")>
        <WorkItem(2598, "https://github.com/dotnet/roslyn/issues/2598")>
        Public Sub EffectiveSeverity_DiagnosticDefault2()
            Dim specificOptions = New Dictionary(Of String, ReportDiagnostic) From {{"Test0001", ReportDiagnostic.Default}}
            Dim generalOption = ReportDiagnostic.Error
 
            TestEffectiveSeverity(DiagnosticSeverity.Warning, expectedEffectiveSeverity:=ReportDiagnostic.Warn, specificOptions:=specificOptions, generalOption:=generalOption)
        End Sub
 
        <Fact>
        <WorkItem(1107500, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1107500")>
        <WorkItem(2598, "https://github.com/dotnet/roslyn/issues/2598")>
        Public Sub EffectiveSeverity_GeneralOption()
            Dim generalOption = ReportDiagnostic.Error
            TestEffectiveSeverity(DiagnosticSeverity.Warning, expectedEffectiveSeverity:=generalOption, generalOption:=generalOption)
        End Sub
 
        <Fact>
        <WorkItem(1107500, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1107500")>
        <WorkItem(2598, "https://github.com/dotnet/roslyn/issues/2598")>
        Public Sub EffectiveSeverity_SpecificOption()
            Dim specificOption = ReportDiagnostic.Suppress
            Dim specificOptions = New Dictionary(Of String, ReportDiagnostic) From {{"Test0001", specificOption}}
            Dim generalOption = ReportDiagnostic.Error
 
            TestEffectiveSeverity(DiagnosticSeverity.Warning, expectedEffectiveSeverity:=specificOption, specificOptions:=specificOptions, generalOption:=generalOption)
        End Sub
 
        <Fact>
        <WorkItem(1107500, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1107500")>
        <WorkItem(2598, "https://github.com/dotnet/roslyn/issues/2598")>
        Public Sub EffectiveSeverity_GeneralOptionDoesNotEnableDisabledDiagnostic()
            Dim generalOption = ReportDiagnostic.Error
            Dim enabledByDefault = False
 
            TestEffectiveSeverity(DiagnosticSeverity.Warning, expectedEffectiveSeverity:=ReportDiagnostic.Suppress, generalOption:=generalOption, isEnabledByDefault:=enabledByDefault)
        End Sub
 
        <Fact>
        <WorkItem(1107500, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1107500")>
        <WorkItem(2598, "https://github.com/dotnet/roslyn/issues/2598")>
        Public Sub EffectiveSeverity_SpecificOptionEnablesDisabledDiagnostic()
            Dim specificOption = ReportDiagnostic.Warn
            Dim specificOptions = New Dictionary(Of String, ReportDiagnostic) From {{"Test0001", specificOption}}
            Dim generalOption = ReportDiagnostic.Error
            Dim enabledByDefault = False
 
            TestEffectiveSeverity(DiagnosticSeverity.Warning, expectedEffectiveSeverity:=specificOption, specificOptions:=specificOptions, generalOption:=generalOption, isEnabledByDefault:=enabledByDefault)
        End Sub
 
        <Fact, WorkItem(6998, "https://github.com/dotnet/roslyn/issues/6998")>
        Public Sub TestGeneratedCodeAnalyzer()
            Dim source = <![CDATA[
<System.CodeDom.Compiler.GeneratedCodeAttribute("tool", "version")> _
Class GeneratedCode{0}
	Private Class Nested{0}
        Private Sub NestedMethod()
            System.Console.WriteLine(0)
        End Sub
	End Class

    Private Sub GeneratedCodeMethod()
        System.Console.WriteLine(0)
    End Sub
End Class

Class NonGeneratedCode{0}
	<System.CodeDom.Compiler.GeneratedCodeAttribute("tool", "version")> _
	Private Class NestedGeneratedCode{0}
        Private Sub NestedGeneratedCodeMethod()
            System.Console.WriteLine(0)
        End Sub
	End Class

    Private Sub NonGeneratedCodeMethod()
        System.Console.WriteLine(0)
    End Sub
End Class
]]>.Value
 
            Dim generatedFileNames =
                {"TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.vb", "Test.designer.vb", "Test.Designer.vb", "Test.generated.vb", "Test.g.vb", "Test.g.i.vb"}
 
            Dim builder = ImmutableArray.CreateBuilder(Of SyntaxTree)()
            Dim treeNum As Integer = 0
 
            ' Trees with non-generated code file names
            Dim tree = VisualBasicSyntaxTree.ParseText(String.Format(source, treeNum), path:="SourceFileRegular.vb")
            builder.Add(tree)
            treeNum = treeNum + 1
 
            tree = VisualBasicSyntaxTree.ParseText(String.Format(source, treeNum), path:="AssemblyInfo.vb")
            builder.Add(tree)
            treeNum = treeNum + 1
 
            ' Trees with generated code file names
            For Each fileName In generatedFileNames
                tree = VisualBasicSyntaxTree.ParseText(String.Format(source, treeNum), path:=fileName)
                builder.Add(tree)
                treeNum = treeNum + 1
            Next
 
            ' Tree with '<auto-generated>' comment
            Dim autoGeneratedPrefixes = {"' <auto-generated> ", "' <autogenerated> "}
            For i = 0 To autoGeneratedPrefixes.Length - 1
                Dim autoGeneratedPrefix = autoGeneratedPrefixes(i)
                tree = VisualBasicSyntaxTree.ParseText(String.Format(autoGeneratedPrefix + source, treeNum), path:=$"SourceFileWithAutoGeneratedComment{i}.vb")
                builder.Add(tree)
                treeNum = treeNum + 1
            Next
 
            ' Verify no compiler diagnostics.
            Dim trees = builder.ToImmutable()
            Dim compilation = CreateCompilationWithMscorlib461(trees.ToArray(), {SystemRef}, TestOptions.ReleaseDll)
            compilation.VerifyDiagnostics()
 
            Dim isGeneratedFile As Func(Of String, Boolean) = Function(fileName) fileName.Contains("SourceFileWithAutoGeneratedComment") OrElse generatedFileNames.Contains(fileName)
 
            ' (1) Verify default mode of analysis when there is no generated code configuration.
            VerifyGeneratedCodeAnalyzerDiagnostics(compilation, isGeneratedFile, generatedCodeAnalysisFlagsOpt:=Nothing)
 
            ' (2) Verify ConfigureGeneratedCodeAnalysis with different combinations of GeneratedCodeAnalysisFlags.
            VerifyGeneratedCodeAnalyzerDiagnostics(compilation, isGeneratedFile, GeneratedCodeAnalysisFlags.None)
            VerifyGeneratedCodeAnalyzerDiagnostics(compilation, isGeneratedFile, AnalyzerDriver.DefaultGeneratedCodeAnalysisFlags)
            VerifyGeneratedCodeAnalyzerDiagnostics(compilation, isGeneratedFile, GeneratedCodeAnalysisFlags.Analyze)
            VerifyGeneratedCodeAnalyzerDiagnostics(compilation, isGeneratedFile, GeneratedCodeAnalysisFlags.ReportDiagnostics)
            VerifyGeneratedCodeAnalyzerDiagnostics(compilation, isGeneratedFile, GeneratedCodeAnalysisFlags.Analyze Or GeneratedCodeAnalysisFlags.ReportDiagnostics)
 
            ' (4) Ensure warnaserror doesn't produce noise in generated files.
            Dim options = compilation.Options.WithGeneralDiagnosticOption(ReportDiagnostic.Error)
            Dim warnAsErrorCompilation = compilation.WithOptions(options)
            VerifyGeneratedCodeAnalyzerDiagnostics(warnAsErrorCompilation, isGeneratedFile, generatedCodeAnalysisFlagsOpt:=Nothing)
        End Sub
 
        <Fact, WorkItem(6998, "https://github.com/dotnet/roslyn/issues/6998")>
        Public Sub TestGeneratedCodeAnalyzerPartialType()
            Dim source As String = <![CDATA['
<System.CodeDom.Compiler.GeneratedCodeAttribute("tool", "version")> _
Partial Class PartialType
End Class

Partial Class PartialType
End Class
]]>.Value
            Dim tree = VisualBasicSyntaxTree.ParseText(source, path:="SourceFileRegular.vb")
            Dim compilation = CreateCompilationWithMscorlib461({tree}, {SystemRef}, TestOptions.ReleaseDll)
            compilation.VerifyDiagnostics()
 
            Dim builder = ArrayBuilder(Of DiagnosticDescription).GetInstance()
 
            ' Expected symbol diagnostics
            Dim squiggledText = "PartialType"
            Dim diagnosticArgument = squiggledText
            Dim line = 3
            Dim column = 15
            AddExpectedLocalDiagnostics(builder, False, squiggledText, line, column, GeneratedCodeAnalysisFlags.ReportDiagnostics, diagnosticArgument)
 
            ' Expected tree diagnostics
            squiggledText = "Class"
            diagnosticArgument = tree.FilePath
            line = 7
            column = 5
            AddExpectedLocalDiagnostics(builder, False, squiggledText, line, column, GeneratedCodeAnalysisFlags.ReportDiagnostics, diagnosticArgument)
 
            ' Expected compilation diagnostics
            AddExpectedNonLocalDiagnostic(builder, GeneratedCodeAnalyzer.Summary, "PartialType(IsGeneratedCode:False)", $"{compilation.SyntaxTrees(0).FilePath}(IsGeneratedCode:False)")
 
            Dim expected = builder.ToArrayAndFree()
 
            VerifyGeneratedCodeAnalyzerDiagnostics(compilation, expected, generatedCodeAnalysisFlagsOpt:=Nothing)
            VerifyGeneratedCodeAnalyzerDiagnostics(compilation, expected, GeneratedCodeAnalysisFlags.None)
            VerifyGeneratedCodeAnalyzerDiagnostics(compilation, expected, AnalyzerDriver.DefaultGeneratedCodeAnalysisFlags)
            VerifyGeneratedCodeAnalyzerDiagnostics(compilation, expected, GeneratedCodeAnalysisFlags.Analyze)
            VerifyGeneratedCodeAnalyzerDiagnostics(compilation, expected, GeneratedCodeAnalysisFlags.ReportDiagnostics)
            VerifyGeneratedCodeAnalyzerDiagnostics(compilation, expected, GeneratedCodeAnalysisFlags.Analyze Or GeneratedCodeAnalysisFlags.ReportDiagnostics)
        End Sub
 
        Friend Class OwningSymbolTestAnalyzer
            Inherits DiagnosticAnalyzer
 
            Public Shared ReadOnly ExpressionDescriptor As New DiagnosticDescriptor("Expression", "Expression", "Expression found.", "Testing", DiagnosticSeverity.Warning, isEnabledByDefault:=True)
 
            Public NotOverridable Overrides ReadOnly Property SupportedDiagnostics As ImmutableArray(Of DiagnosticDescriptor)
                Get
                    Return ImmutableArray.Create(ExpressionDescriptor)
                End Get
            End Property
 
            Public NotOverridable Overrides Sub Initialize(context As AnalysisContext)
                context.RegisterSyntaxNodeAction(
                     Sub(nodeContext)
                         If nodeContext.ContainingSymbol.Name.StartsWith("Funky") AndAlso nodeContext.Compilation.Language = "Visual Basic" Then
                             nodeContext.ReportDiagnostic(CodeAnalysis.Diagnostic.Create(ExpressionDescriptor, nodeContext.Node.GetLocation()))
                         End If
                     End Sub,
                     SyntaxKind.IdentifierName,
                     SyntaxKind.NumericLiteralExpression)
            End Sub
        End Class
 
        <Fact>
        Public Sub OwningSymbolVisualBasic()
            Dim source = <compilation>
                             <file name="c.vb">
                                 <![CDATA[
Class C
    Public Sub UnFunkyMethod()
        Dim x As Integer = 0
        Dim y As Integer = x
    End Sub

    Public Sub FunkyMethod()
        Dim x As Integer = 0
        Dim y As Integer = x
    End Sub

    Public FunkyField As Integer = 12
    Public UnFunkyField As Integer = 12
End Class
]]>
                             </file>
                         </compilation>
 
            Dim comp = CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntime(source)
            comp.VerifyDiagnostics()
            comp.VerifyAnalyzerDiagnostics({New OwningSymbolTestAnalyzer}, Nothing, Nothing,
                Diagnostic(OwningSymbolTestAnalyzer.ExpressionDescriptor.Id, "0").WithLocation(8, 28),
                Diagnostic(OwningSymbolTestAnalyzer.ExpressionDescriptor.Id, "x").WithLocation(9, 28),
                Diagnostic(OwningSymbolTestAnalyzer.ExpressionDescriptor.Id, "12").WithLocation(12, 36))
        End Sub
 
        <Fact, WorkItem(8753, "https://github.com/dotnet/roslyn/issues/8753")>
        Public Sub TestParametersAnalyzer_InRegularMethods()
            Dim source = <compilation>
                             <file name="c.vb">
                                 <![CDATA[
Class C
    Public Sub M(a As Integer, b As String)
    End Sub
End Class
]]>
                             </file>
                         </compilation>
 
            Dim comp = CreateCompilationWithMscorlib40AndVBRuntime(source)
            comp.VerifyDiagnostics()
            comp.VerifyAnalyzerDiagnostics({New AnalyzerForParameters}, Nothing, Nothing,
                Diagnostic("Parameter_ID", "a").WithLocation(2, 18),
                Diagnostic("Parameter_ID", "b").WithLocation(2, 32))
        End Sub
 
        <Fact, WorkItem(8753, "https://github.com/dotnet/roslyn/issues/8753")>
        Public Sub TestParametersAnalyzer_InConstructors()
            Dim source = <compilation>
                             <file name="c.vb">
                                 <![CDATA[
Class C
    Public Sub New(a As Integer, b As String)
    End Sub
End Class
]]>
                             </file>
                         </compilation>
 
            Dim comp = CreateCompilationWithMscorlib40AndVBRuntime(source)
            comp.VerifyDiagnostics()
            comp.VerifyAnalyzerDiagnostics({New AnalyzerForParameters}, Nothing, Nothing,
                Diagnostic("Parameter_ID", "a").WithLocation(2, 20),
                Diagnostic("Parameter_ID", "b").WithLocation(2, 34))
        End Sub
 
        <Fact, WorkItem(8753, "https://github.com/dotnet/roslyn/issues/8753")>
        Public Sub TestParametersAnalyzer_InIndexers()
            Dim source = <compilation>
                             <file name="c.vb">
                                 <![CDATA[
Class C
    Default Public Property Item(a As Integer, b As Integer) As Integer
        Get
            Return 0
        End Get
        Set(ByVal Value As Integer)
        End Set
    End Property
End Class
]]>
                             </file>
                         </compilation>
 
            Dim comp = CreateCompilationWithMscorlib40AndVBRuntime(source)
            comp.VerifyDiagnostics()
            comp.VerifyAnalyzerDiagnostics({New AnalyzerForParameters}, Nothing, Nothing,
                Diagnostic("Parameter_ID", "a").WithLocation(2, 34),
                Diagnostic("Parameter_ID", "b").WithLocation(2, 48),
                Diagnostic("Parameter_ID", "Value").WithLocation(6, 19))
        End Sub
 
        <Fact(Skip:="https://github.com/dotnet/roslyn/issues/14062"), WorkItem(8753, "https://github.com/dotnet/roslyn/issues/8753")>
        Public Sub TestParametersAnalyzer_InDelegateTypes()
            Dim source = <compilation>
                             <file name="c.vb">
                                 <![CDATA[
Class C
    Delegate Sub DelegateType(a As Integer, b As String)
End Class
]]>
                             </file>
                         </compilation>
 
            Dim comp = CreateCompilationWithMscorlib40AndVBRuntime(source)
            comp.VerifyDiagnostics()
            comp.VerifyAnalyzerDiagnostics({New AnalyzerForParameters}, Nothing, Nothing,
                Diagnostic("Parameter_ID", "a").WithLocation(2, 34),
                Diagnostic("Parameter_ID", "b").WithLocation(2, 48))
        End Sub
 
        <Fact, WorkItem(8753, "https://github.com/dotnet/roslyn/issues/8753")>
        Public Sub TestParametersAnalyzer_InOperators()
            Dim source = <compilation>
                             <file name="c.vb">
                                 <![CDATA[
Class C
    Public Shared Operator +(ByVal h1 As C, ByVal h2 As C)
        Return New C()
    End Operator
End Class
]]>
                             </file>
                         </compilation>
 
            Dim comp = CreateCompilationWithMscorlib40AndVBRuntime(source)
            comp.VerifyDiagnostics()
            comp.VerifyAnalyzerDiagnostics({New AnalyzerForParameters}, Nothing, Nothing,
                Diagnostic("Parameter_ID", "h1").WithLocation(2, 36),
                Diagnostic("Parameter_ID", "h2").WithLocation(2, 51))
        End Sub
 
        <Fact, WorkItem(8753, "https://github.com/dotnet/roslyn/issues/8753")>
        Public Sub TestParametersAnalyzer_InInterfaceImplementations()
            Dim source = <compilation>
                             <file name="c.vb">
                                 <![CDATA[
Interface I
    Sub M(a As Integer, b As String)
End Interface

Class C
    Implements I
    Public Sub M(a As Integer, b As String) Implements I.M
    End Sub
End Class
]]>
                             </file>
                         </compilation>
 
            Dim comp = CreateCompilationWithMscorlib40AndVBRuntime(source)
            comp.VerifyDiagnostics()
            comp.VerifyAnalyzerDiagnostics({New AnalyzerForParameters}, Nothing, Nothing,
                Diagnostic("Parameter_ID", "a").WithLocation(2, 11),
                Diagnostic("Parameter_ID", "b").WithLocation(2, 25),
                Diagnostic("Parameter_ID", "a").WithLocation(7, 18),
                Diagnostic("Parameter_ID", "b").WithLocation(7, 32))
        End Sub
 
        <Fact, WorkItem(8753, "https://github.com/dotnet/roslyn/issues/8753")>
        Public Sub TestParametersAnalyzer_InParameterizedProperties()
            Dim source = <compilation>
                             <file name="c.vb">
                                 <![CDATA[
Class C
    Public ReadOnly Property Test(a As Integer, b As String) As Integer
        Get
            Return 1
        End Get
    End Property
End Class
]]>
                             </file>
                         </compilation>
 
            Dim comp = CreateCompilationWithMscorlib40AndVBRuntime(source)
            comp.VerifyDiagnostics()
            comp.VerifyAnalyzerDiagnostics({New AnalyzerForParameters}, Nothing, Nothing,
                Diagnostic("Parameter_ID", "a").WithLocation(2, 35),
                Diagnostic("Parameter_ID", "b").WithLocation(2, 49))
        End Sub
 
        Private Shared Sub VerifyGeneratedCodeAnalyzerDiagnostics(compilation As Compilation, isGeneratedFileName As Func(Of String, Boolean), generatedCodeAnalysisFlagsOpt As GeneratedCodeAnalysisFlags?)
            Dim expected = GetExpectedGeneratedCodeAnalyzerDiagnostics(compilation, isGeneratedFileName, generatedCodeAnalysisFlagsOpt)
            VerifyGeneratedCodeAnalyzerDiagnostics(compilation, expected, generatedCodeAnalysisFlagsOpt, testIsGeneratedCodeInCallbacks:=True)
        End Sub
 
        Private Shared Sub VerifyGeneratedCodeAnalyzerDiagnostics(compilation As Compilation, expected As DiagnosticDescription(), generatedCodeAnalysisFlagsOpt As GeneratedCodeAnalysisFlags?, Optional testIsGeneratedCodeInCallbacks As Boolean = False)
            Dim analyzers = New DiagnosticAnalyzer() {New GeneratedCodeAnalyzer(generatedCodeAnalysisFlagsOpt, testIsGeneratedCodeInCallbacks)}
            compilation.VerifyAnalyzerDiagnostics(analyzers, Nothing, Nothing, expected)
        End Sub
 
        Private Shared Function GetExpectedGeneratedCodeAnalyzerDiagnostics(compilation As Compilation, isGeneratedFileName As Func(Of String, Boolean), generatedCodeAnalysisFlagsOpt As GeneratedCodeAnalysisFlags?) As DiagnosticDescription()
            Dim analyzers = New DiagnosticAnalyzer() {New GeneratedCodeAnalyzer(generatedCodeAnalysisFlagsOpt, testIsGeneratedCodeInCallbacks:=True)}
            Dim files = compilation.SyntaxTrees.Select(Function(t) t.FilePath).ToImmutableArray()
            Dim sortedCallbackSymbolNames = New SortedSet(Of String)()
            Dim sortedCallbackTreePaths = New SortedSet(Of String)()
            Dim sortedCallbackSyntaxNodeNames = New SortedSet(Of String)()
            Dim sortedCallbackOperationNames = New SortedSet(Of String)()
            Dim sortedCallbackSemanticModelPaths = New SortedSet(Of String)()
            Dim sortedCallbackSymbolStartNames = New SortedSet(Of String)()
            Dim sortedCallbackSymbolEndNames = New SortedSet(Of String)()
            Dim sortedCallbackOperationBlockStartNames = New SortedSet(Of String)()
            Dim sortedCallbackOperationBlockEndNames = New SortedSet(Of String)()
            Dim sortedCallbackOperationBlockNames = New SortedSet(Of String)()
            Dim sortedCallbackCodeBlockStartNames = New SortedSet(Of String)()
            Dim sortedCallbackCodeBlockEndNames = New SortedSet(Of String)()
            Dim sortedCallbackCodeBlockNames = New SortedSet(Of String)()
            Dim builder = ArrayBuilder(Of DiagnosticDescription).GetInstance()
            For i As Integer = 0 To compilation.SyntaxTrees.Count() - 1
                Dim file = files(i)
                Dim isGeneratedFile = isGeneratedFileName(file)
 
                ' Type "GeneratedCode{0}"
                Dim squiggledText = String.Format("GeneratedCode{0}", i)
                Dim diagnosticArgument = squiggledText
                Dim line = 3
                Dim column = 7
                Dim isGeneratedCode = True
                AddExpectedLocalDiagnostics(builder, isGeneratedCode, squiggledText, line, column, generatedCodeAnalysisFlagsOpt, diagnosticArgument)
 
                ' Type "Nested{0}"
                squiggledText = String.Format("Nested{0}", i)
                diagnosticArgument = squiggledText
                line = 4
                column = 16
                isGeneratedCode = True
                AddExpectedLocalDiagnostics(builder, isGeneratedCode, squiggledText, line, column, generatedCodeAnalysisFlagsOpt, diagnosticArgument)
 
                ' Type "NonGeneratedCode{0}"
                squiggledText = String.Format("NonGeneratedCode{0}", i)
                diagnosticArgument = squiggledText
                line = 15
                column = 7
                isGeneratedCode = isGeneratedFile
                AddExpectedLocalDiagnostics(builder, isGeneratedCode, squiggledText, line, column, generatedCodeAnalysisFlagsOpt, diagnosticArgument)
 
                ' Type "NestedGeneratedCode{0}"
                squiggledText = String.Format("NestedGeneratedCode{0}", i)
                diagnosticArgument = squiggledText
                line = 17
                column = 16
                isGeneratedCode = True
                AddExpectedLocalDiagnostics(builder, isGeneratedCode, squiggledText, line, column, generatedCodeAnalysisFlagsOpt, diagnosticArgument)
 
                ' File diagnostic
                squiggledText = "Class" ' last token in file.
                diagnosticArgument = file
                line = 26
                column = 5
                isGeneratedCode = isGeneratedFile
                AddExpectedLocalDiagnostics(builder, isGeneratedCode, squiggledText, line, column, generatedCodeAnalysisFlagsOpt, diagnosticArgument)
 
                ' Compilation end summary diagnostic (verify callbacks into analyzer)
                ' Analyzer always called for generated code, unless generated code analysis is explicitly disabled.
                Dim addNames As Action(Of SortedSet(Of String)) = Nothing
                Dim addPath As Action(Of SortedSet(Of String)) = Nothing
                Dim index = i
                If generatedCodeAnalysisFlagsOpt Is Nothing OrElse (generatedCodeAnalysisFlagsOpt And GeneratedCodeAnalysisFlags.Analyze) <> 0 Then
                    addNames = Sub(names As SortedSet(Of String))
                                   names.Add(String.Format("GeneratedCode{0}(IsGeneratedCode:True)", index))
                                   names.Add(String.Format("Nested{0}(IsGeneratedCode:True)", index))
                                   names.Add(String.Format("NonGeneratedCode{0}(IsGeneratedCode:{1})", index, isGeneratedFile))
                                   names.Add(String.Format("NestedGeneratedCode{0}(IsGeneratedCode:True)", index))
                               End Sub
 
                    addPath = Sub(paths As SortedSet(Of String))
                                  paths.Add($"{file}(IsGeneratedCode:{isGeneratedFile})")
                              End Sub
                ElseIf Not isGeneratedFile Then
                    ' Analyzer always called for non-generated code.
                    addNames = Sub(names As SortedSet(Of String))
                                   names.Add(String.Format("NonGeneratedCode{0}(IsGeneratedCode:False)", index))
                               End Sub
 
                    addPath = Sub(paths As SortedSet(Of String))
                                  paths.Add($"{file}(IsGeneratedCode:False)")
                              End Sub
                End If
 
                If addNames IsNot Nothing Then
                    addNames(sortedCallbackSymbolNames)
                    addNames(sortedCallbackSyntaxNodeNames)
                    addNames(sortedCallbackSymbolStartNames)
                    addNames(sortedCallbackSymbolEndNames)
                    addNames(sortedCallbackOperationNames)
                    addNames(sortedCallbackOperationBlockStartNames)
                    addNames(sortedCallbackOperationBlockEndNames)
                    addNames(sortedCallbackOperationBlockNames)
                    addNames(sortedCallbackCodeBlockStartNames)
                    addNames(sortedCallbackCodeBlockEndNames)
                    addNames(sortedCallbackCodeBlockNames)
                End If
 
                If addPath IsNot Nothing Then
                    addPath(sortedCallbackTreePaths)
                    addPath(sortedCallbackSemanticModelPaths)
                End If
            Next
 
            ' Compilation end summary diagnostic (verify callbacks into analyzer)
            Dim arg1 = sortedCallbackSymbolNames.Join(",")
            Dim arg2 = sortedCallbackTreePaths.Join(",")
            Dim arg3 = sortedCallbackSyntaxNodeNames.Join(",") + ";" +
                sortedCallbackOperationNames.Join(",") + ";" +
                sortedCallbackSemanticModelPaths.Join(",") + ";" +
                sortedCallbackSymbolStartNames.Join(",") + ";" +
                sortedCallbackSymbolEndNames.Join(",") + ";" +
                sortedCallbackOperationBlockStartNames.Join(",") + ";" +
                sortedCallbackOperationBlockEndNames.Join(",") + ";" +
                sortedCallbackOperationBlockNames.Join(",") + ";" +
                sortedCallbackCodeBlockStartNames.Join(",") + ";" +
                sortedCallbackCodeBlockEndNames.Join(",") + ";" +
                sortedCallbackCodeBlockNames.Join(",")
            AddExpectedNonLocalDiagnostic(builder, GeneratedCodeAnalyzer.Summary2, {arg1, arg2, arg3})
 
            If compilation.Options.GeneralDiagnosticOption = ReportDiagnostic.Error Then
                For i As Integer = 0 To builder.Count - 1
                    If DirectCast(builder(i).Code, String) <> GeneratedCodeAnalyzer.Error.Id Then
                        builder(i) = builder(i).WithWarningAsError(True)
                    End If
                Next
            End If
 
            Return builder.ToArrayAndFree()
        End Function
 
        Private Shared Sub AddExpectedLocalDiagnostics(
            builder As ArrayBuilder(Of DiagnosticDescription),
            isGeneratedCode As Boolean,
            squiggledText As String,
            line As Integer,
            column As Integer,
            generatedCodeAnalysisFlagsOpt As GeneratedCodeAnalysisFlags?,
            ParamArray arguments As String())
 
            ' Always report diagnostics in generated code, unless explicitly suppressed or we are not even analyzing generated code.
            Dim reportInGeneratedCode = generatedCodeAnalysisFlagsOpt Is Nothing OrElse
                ((generatedCodeAnalysisFlagsOpt.GetValueOrDefault() And GeneratedCodeAnalysisFlags.ReportDiagnostics) <> 0 AndAlso
                 (generatedCodeAnalysisFlagsOpt.GetValueOrDefault() And GeneratedCodeAnalysisFlags.Analyze) <> 0)
 
            If Not isGeneratedCode OrElse reportInGeneratedCode Then
                Dim diag = Diagnostic(GeneratedCodeAnalyzer.Warning.Id, squiggledText).WithArguments(arguments).WithLocation(line, column)
                builder.Add(diag)
 
                diag = Diagnostic(GeneratedCodeAnalyzer.Error.Id, squiggledText).WithArguments(arguments).WithLocation(line, column)
                builder.Add(diag)
            End If
        End Sub
 
        Private Shared Sub AddExpectedNonLocalDiagnostic(builder As ArrayBuilder(Of DiagnosticDescription), descriptor As DiagnosticDescriptor, ParamArray arguments As String())
            AddExpectedDiagnostic(builder, descriptor.Id, Nothing, 1, 1, arguments)
        End Sub
 
        Private Shared Sub AddExpectedDiagnostic(builder As ArrayBuilder(Of DiagnosticDescription), diagnosticId As String, squiggledText As String, line As Integer, column As Integer, ParamArray arguments As String())
            Dim diag = Diagnostic(diagnosticId, squiggledText).WithArguments(arguments).WithLocation(line, column)
            builder.Add(diag)
        End Sub
 
        <DiagnosticAnalyzer(LanguageNames.VisualBasic)>
        Friend NotInheritable Class GeneratedCodeAnalyzer
            Inherits AbstractGeneratedCodeAnalyzer(Of SyntaxKind)
 
            Public Sub New(generatedCodeAnalysisFlags As GeneratedCodeAnalysisFlags?, Optional testIsGeneratedCodeInCallbacks As Boolean = False)
                MyBase.New(generatedCodeAnalysisFlags, testIsGeneratedCodeInCallbacks)
            End Sub
 
            Protected Overrides ReadOnly Property ClassDeclarationSyntaxKind As SyntaxKind
                Get
                    Return SyntaxKind.ClassBlock
                End Get
            End Property
        End Class
 
        <Fact, WorkItem(23309, "https://github.com/dotnet/roslyn/issues/23309")>
        Public Sub TestFieldReferenceAnalyzer_InAttributes()
            Dim source = <compilation>
                             <file name="c.vb">
                                 <![CDATA[
Imports System

<Assembly: MyAttribute(C.FieldForAssembly)>
<Module: MyAttribute(C.FieldForModule)>

Friend Class MyAttribute
    Inherits Attribute
    Public Sub New(f As Integer)
    End Sub
End Class

Friend Interface MyInterface
    Event MyEvent As EventHandler
End Interface

<MyAttribute(C.FieldForClass)>
Friend Class C
    Implements MyInterface
    Friend Const FieldForClass As Integer = 1, FieldForStruct As Integer = 2, FieldForInterface As Integer = 3, FieldForField As Integer = 4, FieldForMethod As Integer = 5,
        FieldForEnum As Integer = 6, FieldForEnumMember As Integer = 7, FieldForDelegateSub As Integer = 8, FieldForDelegateFunction As Integer = 9, FieldForEventField As Integer = 10,
        FieldForEvent As Integer = 11, FieldForAddHandler As Integer = 12, FieldForRemoveHandler As Integer = 13, FieldForRaiseHandler As Integer = 14, FieldForProperty As Integer = 15,
        FieldForPropertyGetter As Integer = 16, FieldForPropertySetter As Integer = 17, FieldForIndexer As Integer = 18, FieldForIndexerGetter As Integer = 19, FieldForIndexerSetter As Integer = 20,
        FieldForMethodParameter As Integer = 21, FieldForEventParameter As Integer = 22, FieldForDelegateSubParameter As Integer = 23, FieldForDelegateFunctionParameter As Integer = 24, FieldForIndexerParameter As Integer = 25,
        FieldForAssembly As Integer = 26, FieldForModule As Integer = 27, FieldForMethodReturnType As Integer = 28, FieldForDelegateFunctionReturnType As Integer = 29, FieldForPropertyReturnType As Integer = 30,
        FieldForIndexerReturnType = 31

    <MyAttribute(FieldForStruct)>
    Private Structure S
    End Structure

    <MyAttribute(FieldForInterface)>
    Private Interface I
    End Interface

    <MyAttribute(FieldForField)>
    Private field2 As Integer = 0, field3 As Integer = 0

    <MyAttribute(FieldForMethod)>
    Private Function M1(<MyAttribute(FieldForMethodParameter)> p1 As Integer) As <MyAttribute(FieldForMethodReturnType)> Integer
        Return 0
    End Function

    <MyAttribute(FieldForEnum)>
    Private Enum E
        <MyAttribute(FieldForEnumMember)>
        F = 0
    End Enum

    <MyAttribute(FieldForDelegateSub)>
    Public Delegate Sub [Delegate](<MyAttribute(FieldForDelegateSubParameter)> p1 As Integer)

    <MyAttribute(FieldForDelegateFunction)>
    Public Delegate Function Delegate2(<MyAttribute(FieldForDelegateFunctionParameter)> p1 As Integer) As <MyAttribute(FieldForDelegateFunctionReturnType)> Integer

    <MyAttribute(FieldForEventField)>
    Public Event MyEvent(<MyAttribute(FieldForEventParameter)> p1 As Integer)

    <MyAttribute(FieldForEvent)>
    Private Custom Event MyEvent2 As EventHandler Implements MyInterface.MyEvent
        <MyAttribute(FieldForAddHandler)>
        AddHandler(ByVal value As EventHandler)
        End AddHandler
        <MyAttribute(FieldForRemoveHandler)>
        RemoveHandler(ByVal value As EventHandler)
        End RemoveHandler
        <MyAttribute(FieldForRaiseHandler)>
        RaiseEvent()
        End RaiseEvent
    End Event

    <MyAttribute(FieldForProperty)>
    Private Property P1() As <MyAttribute(FieldForPropertyReturnType)> Integer
        <MyAttribute(FieldForPropertyGetter)>
        Get
            Return 0
        End Get
        <MyAttribute(FieldForPropertySetter)>
        Set
        End Set
    End Property

    <MyAttribute(FieldForIndexer)>
    Default Property Item(<MyAttribute(FieldForIndexerParameter)> index As Integer) As <MyAttribute(FieldForIndexerReturnType)> Integer
        <MyAttribute(FieldForIndexerGetter)>
        Get
            Return 0
        End Get
        <MyAttribute(FieldForIndexerSetter)>
        Set
        End Set
    End Property
End Class
]]>
                             </file>
                         </compilation>
 
            Dim comp = CreateCompilationWithMscorlib40AndVBRuntime(source)
            comp.VerifyDiagnostics()
 
            ' Test RegisterOperationBlockAction
            TestFieldReferenceAnalyzer_InAttributes_Core(comp, doOperationBlockAnalysis:=True)
 
            ' Test RegisterOperationAction
            TestFieldReferenceAnalyzer_InAttributes_Core(comp, doOperationBlockAnalysis:=False)
        End Sub
 
        Private Shared Sub TestFieldReferenceAnalyzer_InAttributes_Core(comp As Compilation, doOperationBlockAnalysis As Boolean)
            comp.VerifyAnalyzerDiagnostics({New FieldReferenceOperationAnalyzer(doOperationBlockAnalysis)}, Nothing, Nothing,
                Diagnostic("ID", "C.FieldForClass").WithArguments("FieldForClass", "1").WithLocation(16, 14),
                Diagnostic("ID", "FieldForStruct").WithArguments("FieldForStruct", "2").WithLocation(27, 18),
                Diagnostic("ID", "FieldForInterface").WithArguments("FieldForInterface", "3").WithLocation(31, 18),
                Diagnostic("ID", "FieldForField").WithArguments("FieldForField", "4").WithLocation(35, 18),
                Diagnostic("ID", "FieldForField").WithArguments("FieldForField", "4").WithLocation(35, 18),
                Diagnostic("ID", "FieldForMethod").WithArguments("FieldForMethod", "5").WithLocation(38, 18),
                Diagnostic("ID", "FieldForEnum").WithArguments("FieldForEnum", "6").WithLocation(43, 18),
                Diagnostic("ID", "FieldForEnumMember").WithArguments("FieldForEnumMember", "7").WithLocation(45, 22),
                Diagnostic("ID", "FieldForDelegateSub").WithArguments("FieldForDelegateSub", "8").WithLocation(49, 18),
                Diagnostic("ID", "FieldForDelegateFunction").WithArguments("FieldForDelegateFunction", "9").WithLocation(52, 18),
                Diagnostic("ID", "FieldForEventField").WithArguments("FieldForEventField", "10").WithLocation(55, 18),
                Diagnostic("ID", "FieldForEvent").WithArguments("FieldForEvent", "11").WithLocation(58, 18),
                Diagnostic("ID", "FieldForAddHandler").WithArguments("FieldForAddHandler", "12").WithLocation(60, 22),
                Diagnostic("ID", "FieldForRemoveHandler").WithArguments("FieldForRemoveHandler", "13").WithLocation(63, 22),
                Diagnostic("ID", "FieldForRaiseHandler").WithArguments("FieldForRaiseHandler", "14").WithLocation(66, 22),
                Diagnostic("ID", "FieldForProperty").WithArguments("FieldForProperty", "15").WithLocation(71, 18),
                Diagnostic("ID", "FieldForPropertyGetter").WithArguments("FieldForPropertyGetter", "16").WithLocation(73, 22),
                Diagnostic("ID", "FieldForPropertySetter").WithArguments("FieldForPropertySetter", "17").WithLocation(77, 22),
                Diagnostic("ID", "FieldForIndexer").WithArguments("FieldForIndexer", "18").WithLocation(82, 18),
                Diagnostic("ID", "FieldForIndexerGetter").WithArguments("FieldForIndexerGetter", "19").WithLocation(84, 22),
                Diagnostic("ID", "FieldForIndexerSetter").WithArguments("FieldForIndexerSetter", "20").WithLocation(88, 22),
                Diagnostic("ID", "FieldForMethodParameter").WithArguments("FieldForMethodParameter", "21").WithLocation(39, 38),
                Diagnostic("ID", "FieldForEventParameter").WithArguments("FieldForEventParameter", "22").WithLocation(56, 39),
                Diagnostic("ID", "FieldForDelegateSubParameter").WithArguments("FieldForDelegateSubParameter", "23").WithLocation(50, 49),
                Diagnostic("ID", "FieldForDelegateFunctionParameter").WithArguments("FieldForDelegateFunctionParameter", "24").WithLocation(53, 53),
                Diagnostic("ID", "FieldForIndexerParameter").WithArguments("FieldForIndexerParameter", "25").WithLocation(83, 40),
                Diagnostic("ID", "C.FieldForAssembly").WithArguments("FieldForAssembly", "26").WithLocation(3, 24),
                Diagnostic("ID", "C.FieldForModule").WithArguments("FieldForModule", "27").WithLocation(4, 22),
                Diagnostic("ID", "FieldForMethodReturnType").WithArguments("FieldForMethodReturnType", "28").WithLocation(39, 95),
                Diagnostic("ID", "FieldForDelegateFunctionReturnType").WithArguments("FieldForDelegateFunctionReturnType", "29").WithLocation(53, 120),
                Diagnostic("ID", "FieldForPropertyReturnType").WithArguments("FieldForPropertyReturnType", "30").WithLocation(72, 43),
                Diagnostic("ID", "FieldForIndexerReturnType").WithArguments("FieldForIndexerReturnType", "31").WithLocation(83, 101))
        End Sub
 
        <Fact, WorkItem(25167, "https://github.com/dotnet/roslyn/issues/25167")>
        Public Sub TestMethodBodyOperationAnalyzer()
            Dim source = <compilation>
                             <file name="c.vb">
                                 <![CDATA[
Friend Class C
    Sub New()
    End Sub

    Sub M()
    End Sub
End Class
]]>
                             </file>
                         </compilation>
 
            Dim comp = CreateCompilationWithMscorlib40AndVBRuntime(source)
            comp.VerifyDiagnostics()
 
            ' VB methods/constructors don't have an IMethodBodyOperation or an IConstructorBodyOperation.
            comp.VerifyAnalyzerDiagnostics({New MethodOrConstructorBodyOperationAnalyzer()})
        End Sub
 
        <Fact, CompilerTrait(CompilerFeature.IOperation, CompilerFeature.Dataflow)>
        Public Sub TestGetControlFlowGraphInOperationAnalyzers()
            Dim source = <compilation>
                             <file name="c.vb">
                                 <![CDATA[
Class C
    Private Sub M(Optional p As Integer = 0)
        Dim x As Integer = 1 + 2
    End Sub
End Class
]]>
                             </file>
                         </compilation>
 
            Dim comp = CreateCompilationWithMscorlib45AndVBRuntime(source)
            comp.VerifyDiagnostics()
 
            ' 1. Method body flow graph
            ' 2. Parameter initializer flow graph
            Dim expectedFlowGraphs = {
            <![CDATA[
Block[B0] - Entry
    Statements (0)
    Next (Regular) Block[B1]
        Entering: {R1}

.locals {R1}
{
    Locals: [x As System.Int32]
    Block[B1] - Block
        Predecessors: [B0]
        Statements (1)
            ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Int32, IsImplicit) (Syntax: 'x As Integer = 1 + 2')
              Left: 
                ILocalReferenceOperation: x (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Int32, IsImplicit) (Syntax: 'x')
              Right: 
                IBinaryOperation (BinaryOperatorKind.Add, Checked) (OperationKind.Binary, Type: System.Int32, Constant: 3) (Syntax: '1 + 2')
                  Left: 
                    ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 1) (Syntax: '1')
                  Right: 
                    ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 2) (Syntax: '2')

        Next (Regular) Block[B2]
            Leaving: {R1}
}

Block[B2] - Exit
    Predecessors: [B1]
    Statements (0)
]]>.Value,
            <![CDATA[
Block[B0] - Entry
    Statements (0)
    Next (Regular) Block[B1]
Block[B1] - Block
    Predecessors: [B0]
    Statements (1)
        ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Int32, IsImplicit) (Syntax: '= 0')
          Left: 
            IParameterReferenceOperation: p (OperationKind.ParameterReference, Type: System.Int32, IsImplicit) (Syntax: '= 0')
          Right: 
            ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 0) (Syntax: '0')

    Next (Regular) Block[B2]
Block[B2] - Exit
    Predecessors: [B1]
    Statements (0)
]]>.Value}
            ' Verify analyzer diagnostics and flow graphs for different kind of operation analyzers.
 
            Dim analyzer = New OperationAnalyzer(OperationAnalyzer.ActionKind.Operation, verifyGetControlFlowGraph:=True)
            comp.VerifyAnalyzerDiagnostics({analyzer}, Nothing, Nothing,
                Diagnostic("ID", "0").WithArguments("Operation").WithLocation(2, 43),
                Diagnostic("ID", "1").WithArguments("Operation").WithLocation(3, 28),
                Diagnostic("ID", "2").WithArguments("Operation").WithLocation(3, 32))
            verifyFlowGraphs(comp, analyzer.GetControlFlowGraphs(), expectedFlowGraphs)
 
            analyzer = New OperationAnalyzer(OperationAnalyzer.ActionKind.OperationInOperationBlockStart, verifyGetControlFlowGraph:=True)
            comp.VerifyAnalyzerDiagnostics({analyzer}, Nothing, Nothing,
                Diagnostic("ID", "0").WithArguments("OperationInOperationBlockStart").WithLocation(2, 43),
                Diagnostic("ID", "1").WithArguments("OperationInOperationBlockStart").WithLocation(3, 28),
                Diagnostic("ID", "2").WithArguments("OperationInOperationBlockStart").WithLocation(3, 32))
            verifyFlowGraphs(comp, analyzer.GetControlFlowGraphs(), expectedFlowGraphs)
 
            analyzer = New OperationAnalyzer(OperationAnalyzer.ActionKind.OperationBlock, verifyGetControlFlowGraph:=True)
            comp.VerifyAnalyzerDiagnostics({analyzer}, Nothing, Nothing,
                Diagnostic("ID", "M").WithArguments("OperationBlock").WithLocation(2, 17))
            verifyFlowGraphs(comp, analyzer.GetControlFlowGraphs(), expectedFlowGraphs)
 
            analyzer = New OperationAnalyzer(OperationAnalyzer.ActionKind.OperationBlockEnd, verifyGetControlFlowGraph:=True)
            comp.VerifyAnalyzerDiagnostics({analyzer}, Nothing, Nothing,
                Diagnostic("ID", "M").WithArguments("OperationBlockEnd").WithLocation(2, 17))
 
            verifyFlowGraphs(comp, analyzer.GetControlFlowGraphs(), expectedFlowGraphs)
        End Sub
 
        Private Shared Sub verifyFlowGraphs(compilation As Compilation, flowGraphs As ImmutableArray(Of (Graph As ControlFlowGraph, AssociatedSymbol As ISymbol)), expectedFlowGraphs As String())
            For i As Integer = 0 To expectedFlowGraphs.Length - 1
                Dim expectedFlowGraph As String = expectedFlowGraphs(i)
                Dim actualFlowGraphAndSymbol As (Graph As ControlFlowGraph, AssociatedSymbol As ISymbol) = flowGraphs(i)
                ControlFlowGraphVerifier.VerifyGraph(compilation, expectedFlowGraph, actualFlowGraphAndSymbol.Graph, actualFlowGraphAndSymbol.AssociatedSymbol)
            Next
        End Sub
 
        <Fact, WorkItem(30309, "https://github.com/dotnet/roslyn/issues/30309")>
        Public Sub TestSymbolStartAnalyzer_MyApplication()
 
            Dim sources = <compilation>
                              <file name="a.vb"><![CDATA[
Namespace My
    Friend Partial Class MyApplication
    End Class
End Namespace
]]></file>
                          </compilation>
 
            Dim defines = AddPredefinedPreprocessorSymbols(OutputKind.WindowsApplication)
            defines = defines.Add(KeyValuePairUtil.Create("_MyType", CObj("WindowsForms")))
 
            Dim parseOptions = New VisualBasicParseOptions(preprocessorSymbols:=defines)
            Dim compilationOptions = TestOptions.ReleaseExe.WithParseOptions(parseOptions)
 
            Dim compilation = CreateCompilationWithMscorlib40AndVBRuntime(sources, {SystemWindowsFormsRef}, options:=compilationOptions)
            compilation.VerifyDiagnostics()
 
            Dim analyzers = New DiagnosticAnalyzer() {New SymbolStartAnalyzer(topLevelAction:=False, SymbolKind.NamedType)}
            compilation.VerifyAnalyzerDiagnostics(analyzers, Nothing, Nothing,
                Diagnostic("SymbolStartRuleId").WithArguments("MyApplication", "Analyzer1").WithLocation(1, 1))
        End Sub
 
        <Theory, CombinatorialData>
        Public Async Function TestAdditionalFileAnalyzer(registerFromInitialize As Boolean) As Task
            Dim tree = VisualBasicSyntaxTree.ParseText(String.Empty)
            Dim compilation = CreateCompilationWithMscorlib461({tree})
            compilation.VerifyDiagnostics()
 
            Dim additionalFile As AdditionalText = New TestAdditionalText("Additional File Text")
            Dim options = New AnalyzerOptions(ImmutableArray.Create(additionalFile))
            Dim diagnosticSpan = New TextSpan(2, 2)
            Dim analyzer = New AdditionalFileAnalyzer(registerFromInitialize, diagnosticSpan)
            Dim analyzers As ImmutableArray(Of DiagnosticAnalyzer) = ImmutableArray.Create(Of DiagnosticAnalyzer)(analyzer)
 
            Dim diagnostics = Await compilation.WithAnalyzers(analyzers, options).GetAnalyzerDiagnosticsAsync(CancellationToken.None)
            TestAdditionalFileAnalyzer_VerifyDiagnostics(diagnostics, diagnosticSpan, analyzer, additionalFile)
 
            Dim analysisResult = Await compilation.WithAnalyzers(analyzers, options).GetAnalysisResultAsync(additionalFile, CancellationToken.None)
            TestAdditionalFileAnalyzer_VerifyDiagnostics(analysisResult.GetAllDiagnostics(), diagnosticSpan, analyzer, additionalFile)
            TestAdditionalFileAnalyzer_VerifyDiagnostics(analysisResult.AdditionalFileDiagnostics(additionalFile)(analyzer), diagnosticSpan, analyzer, additionalFile)
 
            analysisResult = Await compilation.WithAnalyzers(analyzers, options).GetAnalysisResultAsync(CancellationToken.None)
            TestAdditionalFileAnalyzer_VerifyDiagnostics(analysisResult.GetAllDiagnostics(), diagnosticSpan, analyzer, additionalFile)
            TestAdditionalFileAnalyzer_VerifyDiagnostics(analysisResult.AdditionalFileDiagnostics(additionalFile)(analyzer), diagnosticSpan, analyzer, additionalFile)
        End Function
 
        Private Shared Sub TestAdditionalFileAnalyzer_VerifyDiagnostics(diagnostics As ImmutableArray(Of Diagnostic),
                                                                        expectedDiagnosticSpan As TextSpan,
                                                                        Analyzer As AdditionalFileAnalyzer,
                                                                        additionalFile As AdditionalText)
            Dim diagnostic = Assert.Single(diagnostics)
            Assert.Equal(Analyzer.Descriptor.Id, diagnostic.Id)
            Assert.Equal(LocationKind.ExternalFile, diagnostic.Location.Kind)
            Dim location = DirectCast(diagnostic.Location, ExternalFileLocation)
            Assert.Equal(additionalFile.Path, location.GetLineSpan().Path)
            Assert.Equal(expectedDiagnosticSpan, location.SourceSpan)
        End Sub
 
        <Fact>
        Public Sub TestSemanticModelProvider()
            Dim tree = VisualBasicSyntaxTree.ParseText("
Class C
End Class")
            Dim compilation As Compilation = CreateCompilation({tree})
 
            Dim semanticModelProvider = New MySemanticModelProvider()
            compilation = compilation.WithSemanticModelProvider(semanticModelProvider)
 
            ' Verify semantic model provider is used by Compilation.GetSemanticModel API
            Dim model = compilation.GetSemanticModel(tree)
            semanticModelProvider.VerifyCachedModel(tree, model)
 
            ' Verify semantic model provider is used by VisualBasicCompilation.GetSemanticModel API
            model = CType(compilation, VisualBasicCompilation).GetSemanticModel(tree, ignoreAccessibility:=False)
            semanticModelProvider.VerifyCachedModel(tree, model)
        End Sub
 
        Private NotInheritable Class MySemanticModelProvider
            Inherits SemanticModelProvider
 
            Private ReadOnly _cache As New ConcurrentDictionary(Of SyntaxTree, SemanticModel)()
 
#Disable Warning RSEXPERIMENTAL001 ' Test usage of experimental API
            Public Overrides Function GetSemanticModel(tree As SyntaxTree, compilation As Compilation, Optional options As SemanticModelOptions = SemanticModelOptions.None) As SemanticModel
                Return _cache.GetOrAdd(tree, compilation.CreateSemanticModel(tree, options))
            End Function
 
            Public Sub VerifyCachedModel(tree As SyntaxTree, model As SemanticModel)
                Assert.Same(model, _cache(tree))
            End Sub
        End Class
    End Class
End Namespace