File: Diagnostics\AdditionalFileDiagnosticsTests.vb
Web Access
Project: src\src\EditorFeatures\Test2\Microsoft.CodeAnalysis.EditorFeatures2.UnitTests.vbproj (Microsoft.CodeAnalysis.EditorFeatures2.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 System.Threading.Tasks
Imports Microsoft.CodeAnalysis.CodeActions
Imports Microsoft.CodeAnalysis.CodeFixes
Imports Microsoft.CodeAnalysis.Diagnostics
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.UnitTests
 
Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics.AdditionalFiles
    Public Class AdditionalFileDiagnosticsTests
        Inherits AbstractCrossLanguageUserDiagnosticTest
 
        Private Shared ReadOnly s_compositionWithMockDiagnosticUpdateSourceRegistrationService As TestComposition = EditorTestCompositions.EditorFeatures
 
        Friend Overrides Function CreateDiagnosticProviderAndFixer(workspace As Workspace, language As String) As (DiagnosticAnalyzer, CodeFixProvider)
            Return (New AdditionalFileAnalyzer(), New AdditionalFileFixer())
        End Function
 
        <WpfFact>
        Public Async Function TestAdditionalFiles() As Task
            Dim input =
                <Workspace>
                    <Project Language='C#' AssemblyName='CSharpAssembly1' CommonReferences='true'>
                        <Document FilePath="Test1.cs">
                            using System.Runtime.Serialization;
                            public class Cl$$ass1 : ISerializable
                            {
                                public void GetObjectData(SerializationInfo info, StreamingContext context)
                                {
                                    throw new NotImplementedException();
                                }
                            }
                        </Document>
                    </Project>
                </Workspace>
 
            Using workspace = EditorTestWorkspace.Create(input, composition:=s_compositionWithMockDiagnosticUpdateSourceRegistrationService)
                Dim project = workspace.Projects.First()
                Dim newSln = workspace.CurrentSolution.AddAdditionalDocument(DocumentId.CreateNewId(project.Id), "App.Config", SourceText.From("false"))
                workspace.TryApplyChanges(newSln)
 
                Dim diagnosticAndFix = Await GetDiagnosticAndFixAsync(workspace)
                Dim codeAction = diagnosticAndFix.Item2.Fixes.First().Action
                Dim operations = codeAction.GetOperationsAsync(CancellationToken.None).Result
                Dim edit = operations.OfType(Of ApplyChangesOperation)().First()
 
                Dim oldSolution = workspace.CurrentSolution
                Dim updatedSolution = edit.ChangedSolution
 
                Dim updatedDocument = SolutionUtilities.GetSingleChangedAdditionalDocument(oldSolution, updatedSolution)
 
                Dim actual = updatedDocument.GetTextAsync().Result.ToString().Trim()
 
                Assert.Equal("true", actual)
            End Using
        End Function
    End Class
 
    Public Class AdditionalFileAnalyzer
        Inherits DiagnosticAnalyzer
 
        Public Shared Rule As New DiagnosticDescriptor("OA1001", "Options test", "Serialization support has not been requested", "Test", DiagnosticSeverity.Error, True)
 
        Public Overrides ReadOnly Property SupportedDiagnostics As ImmutableArray(Of DiagnosticDescriptor)
            Get
                Return ImmutableArray.Create(Rule)
            End Get
        End Property
 
        Public Overrides Sub Initialize(context As AnalysisContext)
            context.RegisterSymbolAction(AddressOf AnalyzeSymbol, SymbolKind.NamedType)
        End Sub
 
        Private Shared Function IsSerializationAllowed(options As AnalyzerOptions) As Boolean
            Dim serializationAllowed = False
            For Each item In options.AdditionalFiles
                If item.Path.EndsWith("app.config", StringComparison.OrdinalIgnoreCase) Then
                    Dim text = item.GetText()
                    Boolean.TryParse(text.Lines(0).ToString(), serializationAllowed)
                End If
            Next
 
            Return serializationAllowed
        End Function
 
        Public Shared Sub AnalyzeSymbol(context As SymbolAnalysisContext)
            Dim namedType = DirectCast(context.Symbol, INamedTypeSymbol)
 
            If namedType.AllInterfaces.Contains(context.Compilation.GetTypeByMetadataName("System.Runtime.Serialization.ISerializable")) Then
                If Not IsSerializationAllowed(context.Options) Then
                    context.ReportDiagnostic(Diagnostic.Create(Rule, context.Symbol.Locations.First()))
                End If
            End If
        End Sub
    End Class
 
    Public Class AdditionalFileFixer
        Inherits CodeFixProvider
 
        Public NotOverridable Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String)
            Get
                Return ImmutableArray.Create(AdditionalFileAnalyzer.Rule.Id)
            End Get
        End Property
 
        Public NotOverridable Overrides Async Function RegisterCodeFixesAsync(context As CodeFixContext) As Task
            Dim project = context.Document.Project
 
            Dim appConfigDoc = project.AdditionalDocuments.Where(Function(d) d.Name.EndsWith("app.config", StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault()
 
            If appConfigDoc IsNot Nothing Then
                Dim text = Await appConfigDoc.GetTextAsync().ConfigureAwait(False)
                Dim newText = "true"
                Dim newSln = appConfigDoc.Project.Solution.WithAdditionalDocumentText(appConfigDoc.Id, SourceText.From("true", text.Encoding))
 
#Disable Warning RS0005
                context.RegisterCodeFix(CodeAction.Create("Request serialization permission", Function(ct) Task.FromResult(newSln)), context.Diagnostics)
#Enable Warning RS0005
            End If
        End Function
    End Class
End Namespace